fs-captcha.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <template>
  2. <fs-button
  3. v-if="type === 'button'"
  4. size="medium"
  5. round
  6. :plain="plain"
  7. :block="block"
  8. @click="getCaptcha"
  9. :style="customStyle"
  10. :disabled="state.sending"
  11. >
  12. {{ state.timerText }}
  13. </fs-button>
  14. <view v-else class="primary" :style="customStyle" @click="getCaptcha">{{ state.timerText }}</view>
  15. </template>
  16. <script>
  17. /**
  18. * 验证码组件
  19. * @description 验证码组件
  20. * @property {String} mobile 手机号
  21. * @property {Number} seconds 倒计时(单位s)
  22. * @property {String} type = [button | text] 类型
  23. * @property {Boolean} plain 是否镂空
  24. * @property {Boolean} block 块状
  25. * @property {Object} customStyle 自定义样式
  26. * @event {Function} start 倒计时开始事件
  27. * @event {Function} end 倒计时结束事件
  28. */
  29. export default {
  30. name: 'fs-captcha'
  31. }
  32. </script>
  33. <script setup>
  34. import { reactive } from 'vue'
  35. const props = defineProps({
  36. mobile: String,
  37. seconds: {
  38. type: Number,
  39. default: 60
  40. },
  41. type: {
  42. type: String,
  43. default: 'button',
  44. validator(value) {
  45. return ['button', 'text'].includes(value)
  46. }
  47. },
  48. block: Boolean,
  49. plain: {
  50. type: Boolean,
  51. default: true
  52. },
  53. customStyle: {
  54. type: Object,
  55. default: () => {}
  56. }
  57. })
  58. const emits = defineEmits(['start', 'end'])
  59. const state = reactive({
  60. timerText: '获取验证码',
  61. sending: false,
  62. timerId: null
  63. })
  64. const getCaptcha = () => {
  65. if (!state.sending) {
  66. if (!/^1\d{10}$/.test(props.mobile)) {
  67. return uni.showToast({
  68. icon: 'none',
  69. title: '请输入正确的手机号'
  70. })
  71. }
  72. state.sending = true
  73. let timer = props.seconds
  74. state.timerText = `${timer}s`
  75. state.timerId = setInterval(() => {
  76. if (--timer > 0) {
  77. state.timerText = `${timer}s`
  78. } else {
  79. endSendCaptcha()
  80. }
  81. }, 1000)
  82. emits('start')
  83. }
  84. }
  85. const endSendCaptcha = () => {
  86. state.sending = false
  87. state.timerText = '获取验证码'
  88. clearInterval(state.timerId)
  89. emits('end')
  90. }
  91. </script>
  92. <style></style>