Vue3倒计时组件封装思路

一开始, 我打算封装成一个hooks, 结果封装完成之后, 发现有一些局限性

所以, 干脆封装成一个组件, 并全局注册, 用了直接使用即可

我们先来说一下需求

图片

需求还是非常简单的, 我们一步一步来写吧

首先, 我们需要将组件全局注册

import countDownTime from ‘@/components/countDownTime.vue’
const app = createApp(App)
app.component(‘countDownTime’,countDownTime)
在App.vue中进行使用, 传入一个目标时间time, 绑定一个自定义事件downChange

downChange事件主要是做什么呢, 其实它是接收信息返回, 取消订单和刷新列表

如果感觉写在一块比较麻烦, 可以再绑定一个自定义事件, 来做刷新列表的事情

剩下的逻辑, 我们就需要写在倒计时组件中了, 首先来接收一下传入的time和事件downChange

接收完毕之后, 我们需要几个响应式数据, 比如, 当前时间, 时间差值

import {ref} from ‘vue’

接下来, 就需要获取天, 小时, 分钟, 秒了, 我发现计算这几个东西, 都要依赖响应式差值这个变量, 所以, 基于响应式数据变化, 我们使用computed是最好不过的, 他是有缓存的, 只有依赖的数据发生变化, 才会进行计算

这里, 我们还需要做成国际化的, 所以, 我将useI18n进行了引入

import { useI18n } from ‘vue-i18n’
const {t} = useI18n()
因为, 我们需要的格式是xx天xx小时xx分钟xx秒, 我就写的比较麻烦了

大概就是小于10需要补0, 并且天,小时,分钟,秒需要根据选择语言进行变化

我们在模板中使用, 虽然, 出来的, 但是并没有达成倒计时的效果

这时候, 就需要我们使用定时器了, 但是, 关于定时器我们到底选择哪一种呢?

所以这里需要给大家聊一聊我为什么接下来要选择setTimeout

因为, 我们如果使用setInterval会有两个问题, 一个是使用setInterval时, 某些间隔可能会被跳过, 另一个就是也有可能多个定时器会连续执行, 为什么这样说, 因为setInterval是每隔几秒会往消息队列中添加一个事件, 如果主线程这时候有其他任务在执行, 可能需要等待, 还有就是setInterval将任务push到任务队列的时候, 都需要判断上次的任务是否还在任务队列中, 然而setTimeout正好弥补了setInterval的问题, 会将任务直接push到任务队列中

我们接下来, 回归正题

上面我们使用了计算属性, 所以, 我们直接封装一个定时器函数, 在固定时间内调用该函数即可

我们还需要考虑一种情况, 如果我们只有1000毫秒了, 我们就不需要调用定时器函数了, 所以调用该函数是有前提条件的

// 前提条件, 不能为负值
if(timeRemaining.value > 1000) {
startCountdown()
}
那么倒计时为1000毫秒的时候, 我们就不再调用定时器函数, 需要我们清除定时器

我们上面的isTimeShow用于切换显示状态的

这样, 我们的定时器就算封装完成了, 我们看一下效果

如果, 倒计时结束, 我们显示活动已结束即可

虽然功能实现了, 但是还有很多点需要优化, 比如: 优先判断传入的值是不是NaN, 如果是, 我们就不再执行倒计时逻辑, 比如, 再封装几个字段, 用于天, 小时, 分钟, 秒的显示, 是否国际化等等

定时器的效果, 大家可以点击阅读原文

今天, 我们就讲解到这里

我们下期见

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/414074.html

(0)
联系我们
联系我们
分享本页
返回顶部