Vant 没有提供倒计时按钮组件,手动实现一下。
// CountDownButton.vue 实现
<template>
<Button
style="min-width: 80px;"
size="small"
type="primary"
:disabled="countDownButtonArgs.timing"
@click="emit('click', successCallback)"
>{{ loading ? loadingText : countDownButtonArgs.timing ? countDownButtonArgs.count : buttonText }}</Button>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { Button } from 'vant'
const props = defineProps({
maxSecondNum: {
type: Number,
default: 60
},
buttonText: {
type: String,
default: '获取验证码'
},
loadingText: {
type: String,
default: '发送中'
},
loading: {
type: Boolean,
default: false
}
})
type EmitsType = { (e: 'click', successCallback: () => void): void }
const emit = defineEmits<EmitsType>()
const countDownButtonArgs = reactive<{ timing: boolean; count: number }>({
timing: false,
count: 0
})
const successCallback = () => {
countDownButtonArgs.timing = true
countDownButtonArgs.count = props.maxSecondNum
const timer = setInterval(() => {
const { count } = countDownButtonArgs
if (count > 0 && count <= props.maxSecondNum) {
countDownButtonArgs.count--;
} else {
countDownButtonArgs.timing = false
clearInterval(timer)
countDownButtonArgs.count = 0
}
}, 1000)
}
</script>
<style lang="less">
</style>
// 使用举例
<template>
<div>
<NavBar title="用户登录"></NavBar>
<Form @submit="onLogin">
<CellGroup inset>
<Field
v-model="phone"
name="tel"
label="手机号"
:rules="[{ required: true, message: '请输入' }]"
/>
<Field
v-model="code"
type="password"
name="password"
label="验证码"
:rules="[{ required: true, message: '请输入' }]"
>
<template #button>
<CountDownButton :loading="loading" @click="getCodeFn"></CountDownButton>
</template>
</Field>
</CellGroup>
<div style="margin: 16px;">
<Button round block type="primary" native-type="submit">登录</Button>
</div>
</Form>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { Form, Field, CellGroup, Button, NavBar, Toast } from 'vant'
import CountDownButton from '../../../components/CountDownButton.vue'
import { sendSmsCode, smsLogin } from './api'
import { useRouter } from 'vue-router'
const router = useRouter()
const phone = ref('');
const code = ref('');
const onLogin = async () => {
const b = await smsLogin(phone.value, code.value)
if (b) {
Toast('登录成功')
router.push('/tvs/home')
}
};
const loading = ref(false)
const getCodeFn = async (successCallback: () => void) => {
if (!phone.value) { Toast('请输入手机号'); return; }
loading.value = true
const b = await sendSmsCode(phone.value)
loading.value = false
successCallback()
if (b) { Toast('验证码发送成功'); }
}
</script>
<style lang="less">
</style>
效果如下
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。