【实战分享】Vue3组合式函数封装:获取验证码倒计时

  • 原创
  • 作者:程序员三丰
  • 发布时间:2025-07-25 09:25
  • 浏览量:222
本文分享一个自己封装vue3组合式函数,实现了工作中常用的获取验证码功能倒计时的交互效果,可以解决重复造轮子的问题。

如果你还不了解什么是“组合式函数”,请移步官方文档:
https://cn.vuejs.org/guide/reusability/composables.html

组合式函数源代码

下面的代码块就是完整的验证码倒计时组合式函数的代码,可以直接拿来用在自己的项目中。

// utils/countDown.ts

import { ref, onUnmounted, computed } from 'vue'
import { dayjs } from 'element-plus' // 此处根据项目实际情况导入相应的依赖包
// import * as dayjs from 'dayjs'

/**
 * 倒计时
 * @returns
 */
export function useCountDown() {
    const showLog = ref(false)

    const countDownTimer = ref<any>(null)
    const countDownLimit = ref<number>(60)
    const countDownTextDefault = ref('获取验证码')
    const countDownWorking = ref(false)

    const startTime = ref<string>('')
    const endTime = ref<string>('')

    const startCountDown = () => {
        if (countDownTimer.value && countDownWorking.value) {
            if (showLog.value) {
                console.error('不允许重复启动倒计时!!!')
            }
            return
        }

        startTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss')

        countDownWorking.value = true
        countDownTimer.value = setInterval(() => {
            if (showLog.value) {
                console.log(`IntervalTimer: ${countDownTimer.value}, CurrentCountDownValue: ${countDownLimit.value}`)
            }
            countDownLimit.value--
            if (!countDownLimit.value) {
                resetCountDown()
            }
        }, 1000)
    }

    const resetCountDown = () => {
        if (countDownTimer.value) {
            clearInterval(countDownTimer.value)
            countDownTimer.value = null
            countDownLimit.value = 60
            countDownWorking.value = false

            endTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss')
            const costTime = dayjs(endTime.value).diff(dayjs(startTime.value), 'second')
            if (showLog.value) {
                console.log(`倒计时耗时:${costTime}秒`)
            }
        }
    }

    const countDownText = computed(() => {
        return countDownWorking.value ? `${countDownLimit.value} 秒后重新获取` : countDownTextDefault.value
    })

    onUnmounted(() => {
        resetCountDown()
    })

    return { countDownTimer, countDownLimit, countDownTextDefault, countDownText, countDownWorking, startCountDown, resetCountDown, showLog }
}

使用说明

  1. 在你的项目目录下适当位置创建一个文件名为:countDown.ts(这个文件名可以根据实际需求自行更改);
  2. 然后把上面的代码复制到文件中即可。

这样就在你的项目中创建了一个组合式函数(文件),下面应用部分介绍具体如何使用。

代码结构说明

代码结构很简单,无非就是一些状态和方法,对外暴露的属性可以在调用时对组合式函数进行配置,对外暴露的方法可以进行功能交互控制。下面具体说明:

【暴露的属性】

  • countDownLimit:倒计时的秒数,默认60秒(说明:单位是秒)。
  • countDownTextDefault:倒计时控制DOM容器(一般是按钮元素)默认显示的文本,一般是显示“获取验证码”,点击后变成倒计时相关文本,比如有些极简风格,就需要默认显示“验证码”三个字,那么就可以把这个属性设置为“验证码”即可。
  • countDownText:这是一个计算属性,只读,不支持设置,根据组合式函数的工作状态,动态更新倒计时控制DOM容器显示的文本,如:“28秒后重新获取”。
  • countDownWorking:该属性记录组合式函数的工作状态,值为布尔值true或false,暴露的目的是可以根据它可以外部做一些交互,请不要更改它的值,以免引起异常。
  • countDownTimer:该属性记录组合式内部计时器函数setInterval的值,调用者一般无需关注它,除非特殊需求,请不要更改它的值,以免引起异常。
  • showLog:这是一个开发者选项,值为布尔值true或false,根据字面意思理解即可,设置为true时,运行时会在浏览器控制台打印输出一些运行日志,便于开发者调测。

【暴露的方法】

  • startCountDown:该方法用来启动倒计时。
  • resetCountDown:该方法用来销毁倒计时,并重置为初始化状态。除非你有特殊需要,需要在验证码组合式函数工作状态(也就是倒计时读秒过程中)停止倒计时,否则不要随意调用。

注意事项

  • 处理第三方日期时间库Day.js
    代码中除了使用了vue的api,还是用了第三方的处理日期时间的库Day.js(Day.js中文网),由于我的项目是基于element-plus构建,它内部已经集成了day.js,所以可以直接从element-plus引入。
    如果你的项目不是基于element-plus构建,可能你需要单独安装Days.js并引入才能使用:
# 安装
npm install dayjs
yarn add dayjs
pnpm add dayjs

# 引入
import * as dayjs from 'dayjs'
  • 一个界面中有多个验证码的场景,如何处理?
    我的思路是,正常使用即可,因为实际中即便有多个验证码功能,某一时刻只能是一个场景在使用;
    如果多个验证码某一个时刻只显示一个,那么就正常使用即可,
    如果多个验证码同时展示在页面中,那么一个运行,其他的也会同时更新状态,就是问题,那么解决办法就是,每个验证码单独封装一个组件,这样每个组件就有自己独立的状态。(后续我会整理分享一个demo)

应用

下面的示例代码基于element-plus构建,自己可以根据实际情况进行调整。

<!-- 本示例代码基于element-plus构建 -->

<template>
    <el-button 
        type="primary" 
        @click="onGetCodeClick" 
        style="width: 100%" 
        :disabled="countDownWorking">
        {{ countDownText }}
    </el-button>
</template>

<script setup lang="ts">
    import { useCountDown } from '/@/utils/countDown'
    const { startCountDown, countDownText, countDownWorking, showLog } = useCountDown()

    showLog.value = true // 打开浏览器控制台显示运行日志

    const onGetCodeClick = () => {
        // 此处可以添加自己的业务逻辑,比如检查手机号或者邮箱是否已正确输入,不正确则不触发倒计时
        startCountDown()
    }

</script>

后续我会分享一个完整的手机验证码登录案例来演示本文的组合式函数的实际应用。

声明:本文为原创文章,51blog.xyz和作者拥有版权,如需转载,请注明来源于51blog.xyz并保留原文链接:https://www.51blog.xyz/article/90.html

文章归档

推荐文章

buildadmin logo
Thinkphp8 Vue3 Element PLus TypeScript Vite Pinia

🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。

热门标签

PHP ThinkPHP ThinkPHP5.1 Go Mysql Mysql5.7 Redis Linux CentOS7 Git HTML CSS CSS3 Javascript JQuery Vue LayUI VMware Uniapp 微信小程序 docker wiki Confluence7 学习笔记 uView ES6 Ant Design Pro of Vue React ThinkPHP6.0 chrome 扩展 翻译工具 Nuxt SSR 服务端渲染 scrollreveal.js ThinkPHP8.0 Mac webman 跨域CORS vscode GitHub ECharts Canvas vue3