fs-captcha.vue 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. {{state.timerText}}
  12. </fs-button>
  13. <view v-else class="primary" :style="customStyle" @click="getCaptcha">{{state.timerText}}</view>
  14. </template>
  15. <script setup>
  16. import { reactive } from 'vue'
  17. const props = defineProps({
  18. mobile: String,
  19. seconds: {
  20. type: Number,
  21. default: 60
  22. },
  23. type: {
  24. type: String,
  25. default: 'button',
  26. validator(value) {
  27. return ['button','text'].includes(value)
  28. }
  29. },
  30. block: Boolean,
  31. plain: {
  32. type: Boolean,
  33. default: true
  34. },
  35. customStyle: {
  36. type: Object,
  37. default: () => {}
  38. }
  39. })
  40. const emits = defineEmits(['start', 'end'])
  41. const state = reactive({
  42. timerText: '获取验证码',
  43. sending: false,
  44. timerId: null
  45. })
  46. const getCaptcha = () => {
  47. if (!state.sending) {
  48. if (!/^1\d{10}$/.test(props.mobile)) {
  49. return uni.showToast({
  50. icon: 'none',
  51. title: '请输入正确的手机号'
  52. })
  53. }
  54. state.sending = true
  55. let timer = props.seconds
  56. state.timerText = `${timer}s`
  57. state.timerId = setInterval(() => {
  58. if (--timer > 0) {
  59. state.timerText = `${timer}s`
  60. } else {
  61. endSendCaptcha()
  62. }
  63. }, 1000)
  64. emits('start')
  65. }
  66. }
  67. const endSendCaptcha = () => {
  68. state.sending = false
  69. state.timerText = '获取验证码'
  70. clearInterval(state.timerId)
  71. emits('end')
  72. }
  73. </script>
  74. <style>
  75. </style>