92 lines
1.9 KiB
Vue
92 lines
1.9 KiB
Vue
<template>
|
|
<view class="submit-bar">
|
|
<view
|
|
class="submit-btn"
|
|
:class="{ 'submit-btn--loading': loading }"
|
|
:style="btnStyle"
|
|
@click="handleClick"
|
|
>
|
|
<text v-if="icon" class="submit-btn__icon">{{ icon }}</text>
|
|
<text class="submit-btn__text">{{ loading ? '提交中...' : text }}</text>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
|
|
const props = defineProps({
|
|
text: { type: String, default: '提交' },
|
|
icon: { type: String, default: '' },
|
|
color: { type: String, default: '#2979ff' },
|
|
loading: { type: Boolean, default: false }
|
|
})
|
|
|
|
const emit = defineEmits(['click'])
|
|
|
|
const lighten = (hex, amount = 0.25) => {
|
|
const c = hex.replace('#', '')
|
|
const r = Math.round(parseInt(c.substring(0, 2), 16) * (1 - amount) + 255 * amount)
|
|
const g = Math.round(parseInt(c.substring(2, 4), 16) * (1 - amount) + 255 * amount)
|
|
const b = Math.round(parseInt(c.substring(4, 6), 16) * (1 - amount) + 255 * amount)
|
|
return `rgb(${r},${g},${b})`
|
|
}
|
|
|
|
const btnStyle = computed(() => ({
|
|
background: `linear-gradient(135deg, ${props.color}, ${lighten(props.color)})`,
|
|
boxShadow: `0 6rpx 24rpx ${props.color}4d`
|
|
}))
|
|
|
|
const handleClick = () => {
|
|
if (!props.loading) emit('click')
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
$primary: #2979ff;
|
|
$bg: #f4f2ee;
|
|
|
|
.submit-bar {
|
|
position: fixed;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
z-index: 100;
|
|
padding: 20rpx 24rpx;
|
|
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|
background: linear-gradient(180deg, rgba($bg, 0) 0%, $bg 20%);
|
|
}
|
|
|
|
.submit-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 24rpx;
|
|
border-radius: 14rpx;
|
|
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
|
|
&:active {
|
|
opacity: 0.9;
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
&--loading {
|
|
opacity: 0.7;
|
|
pointer-events: none;
|
|
}
|
|
|
|
&__icon {
|
|
font-size: 30rpx;
|
|
color: #fff;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
&__text {
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
color: #fff;
|
|
letter-spacing: 2rpx;
|
|
}
|
|
}
|
|
</style>
|