效果图:

image.png

使用vueuse官方工具库提供的 useIntervalFn 方法

  1. npm i @vueuse/core
  1. import { useIntervalFn } from '@vueuse/core'

useIntervalFn语法

  1. const {pause, resume } =useIntervalFn(() => {// 具体要做的事情 }, 间隔时间, { immediate: false|true })
  2. pause() // 暂停
  3. resume()// 继续
  4. immediate 是否立即执行

大概思路

HTML

  1. <span class="code" @click="start(60)">

JS 要倒计时的数据time

  1. const time = ref(0)

如果时间大于0 不做任何操作

  1. const start = (num) => {
  2. // 如果大于0 直接return
  3. if (time.value > 0) {
  4. return
  5. }
  6. // 发送Ajax
  7. userMobileLoginMsg(form.mobile).then((res) => console.log(res))
  8. // 赋值
  9. time.value = num
  10. // 调用倒计时
  11. resume()
  12. }

调用 倒计时方法

  1. const { pause, resume } = useIntervalFn(
  2. () => {
  3. // 时间-1
  4. time.value--
  5. // 时间<=0 停止倒计时
  6. if (time.value <= 0) {
  7. pause()
  8. }
  9. },
  10. 1000,
  11. { immediate: false }
  12. )

优化成三个方法

  1. <span class="code" @click="start()">
  2. const time = ref(0)
  3. // pause 停止 resume继续
  4. const { pause, resume } = useIntervalFn(
  5. () => {
  6. time.value--
  7. if (time.value <= 0) {
  8. pause()
  9. }
  10. },
  11. 1000,
  12. { immediate: false }
  13. )
  14. const start = (num) => {
  15. // 赋值
  16. time.value = num
  17. // 调用
  18. resume()
  19. }
  20. const send = () => {
  21. // 如果大于0 直接return
  22. if (time.value > 0) {
  23. return
  24. }
  25. //发送ajax
  26. try {
  27. await userMobileLoginMsg(formData.mobile)
  28. Message({ type: 'success', text: '验证码已经发送!' })
  29. } catch (err) {
  30. console.dir(err)
  31. Message({ type: 'error', text: err.response.data.message })
  32. }
  33. start(60)
  34. }

最终代码+抽离方法

抽离方法

  1. import { ref } from 'vue'
  2. import { useIntervalFn } from '@vueuse/core'
  3. // 倒计时
  4. export const useCountDown = () => {
  5. const time = ref(0)
  6. // pause 停止 resume继续
  7. const { pause, resume } = useIntervalFn(
  8. () => {
  9. time.value--
  10. if (time.value <= 0) {
  11. pause()
  12. }
  13. },
  14. 1000,
  15. { immediate: false }
  16. )
  17. const start = (num) => {
  18. // 赋值
  19. time.value = num
  20. // 调用
  21. resume()
  22. }
  23. return { time, start }
  24. }


组件代码
里面有一些Messag提示框 报错可删除提示框

  1. <span class="code" @click="send()">
  2. {{time === 0 ? "发送验证码" : time+'秒后获取'}}
  3. </span>
  4. <script>
  5. import { useCountDown } from '@/compositions/index'
  6. setup(){
  7. const { start, time } = useCountDown()
  8. const send = async () => {
  9. // 表单效验最后的结果返回ture 否则返回文字(===false是错误写法)
  10. if (mobile(form.mobile) !== true) {
  11. Message({ type: 'error', text: '手机号格式错误' })
  12. return
  13. }
  14. // 如果大于0 直接return
  15. if (time.value > 0) return
  16. // 发送Ajax
  17. try {
  18. await userMobileLoginMsg(form.mobile).then((res) => console.log(res))
  19. Message({ type: 'success', text: '获取验证码成功!' })
  20. } catch (error) {
  21. Message({ type: 'error', text: error.response.data.message || '获取验证码失败!' })
  22. }
  23. start(60)
  24. }
  25. return { time, send }
  26. }
  27. </script>