123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- <template>
- <fs-button
- v-if="type === 'button'"
- size="medium"
- round
- :plain="plain"
- :block="block"
- @click="getCaptcha"
- :style="customStyle"
- :disabled="state.sending"
- >
- {{ state.timerText }}
- </fs-button>
- <view v-else class="primary" :style="customStyle" @click="getCaptcha">{{ state.timerText }}</view>
- </template>
- <script>
- /**
- * 验证码组件
- * @description 验证码组件
- * @property {String} mobile 手机号
- * @property {Number} seconds 倒计时(单位s)
- * @property {String} type = [button | text] 类型
- * @property {Boolean} plain 是否镂空
- * @property {Boolean} block 块状
- * @property {Object} customStyle 自定义样式
- * @event {Function} start 倒计时开始事件
- * @event {Function} end 倒计时结束事件
- */
- export default {
- name: 'fs-captcha'
- }
- </script>
- <script setup>
- import { reactive } from 'vue'
- const props = defineProps({
- mobile: String,
- seconds: {
- type: Number,
- default: 60
- },
- type: {
- type: String,
- default: 'button',
- validator(value) {
- return ['button', 'text'].includes(value)
- }
- },
- block: Boolean,
- plain: {
- type: Boolean,
- default: true
- },
- customStyle: {
- type: Object,
- default: () => {}
- }
- })
- const emits = defineEmits(['start', 'end'])
- const state = reactive({
- timerText: '获取验证码',
- sending: false,
- timerId: null
- })
- const getCaptcha = () => {
- if (!state.sending) {
- if (!/^1\d{10}$/.test(props.mobile)) {
- return uni.showToast({
- icon: 'none',
- title: '请输入正确的手机号'
- })
- }
- state.sending = true
- let timer = props.seconds
- state.timerText = `${timer}s`
- state.timerId = setInterval(() => {
- if (--timer > 0) {
- state.timerText = `${timer}s`
- } else {
- endSendCaptcha()
- }
- }, 1000)
- emits('start')
- }
- }
- const endSendCaptcha = () => {
- state.sending = false
- state.timerText = '获取验证码'
- clearInterval(state.timerId)
- emits('end')
- }
- </script>
- <style></style>
|