需求

  1. 开发一个开箱即用的组件,实现倒计时的效果,显示模式为 01日01时01分01秒。
  2. 以终止时间为入参,计算倒计时显示的各个数据。
  3. 方便的控制显示的文案,以及主题颜色,大小。

组件思路

  1. 组件分为两个部分

    animate-clock,控制组件数据结构,例如:自定义文案、将中文时间单位改成英文,是否换行等等
    animate-card,动画卡片,即组件里面的具体数字部分,并加上动画。
    
  2. clock 组件中,对传入的 props 进行处理,最核心的为 终止时间(terminalTime),根据终止时间计算天、时、分、秒

  3. 通过定时任务,把计算出来的 天、时、分、秒 数据传入 card 组件,触发视图更新。

  4. card 组件中,当数据发生改变的时候触发动画效果。

  5. 【升级】在此基础上进行扩展,变为一个倒计时通用解决方案:

     反向倒计时只有数字的倒计时只有分、秒的倒计时中文、英文字符串倒计时动画抽奖专注时间计时器...
    

开发

首先设计视图部分:

<template><div class="animate-clock"><!-- <p>{{days}}{{hours}}{{minites}}{{seconds}}</p> --><span>距离结束还剩</span><animate-card :val="days" :size="16" :self-disabled="disabled" /><span>天</span><animate-card :val="hours" :size="16" :self-disabled="disabled" /><span>时</span><animate-card :val="minites" :size="16" :self-disabled="disabled" /><span>分</span><animate-card :val="seconds" :size="16" :self-disabled="disabled" /><span>秒</span></div>
</template><style lang="scss" scoped>
.animate-clock {width: 100%;text-align: center;font-size: 16px;font-weight: bold;padding: 40px 0 ;
}
</style>

很简单的结构,现在版本为截图所示的一行结构,可以看到,完全可以通过业务组件中通过传入 props 的形式,修改每一个部分的文案,而且 样式也可以随时控制。

js 部分主要做这么几件事:

 1. 接收 props,并声明 data2. 声明一个 工具函数,用来 处理 小于 10 的数字,前面增加 03. 声明主要业务函数,被定时任务调用的更新数据方法
<script>
import animateCard from './animate-card.vue'export default {components: { animateCard },props: {terminalTime: String,},data() {return {days: ['0', '0'],hours: ['0', '0'],minites: ['0', '0'],seconds: ['0', '0'],setIntVal: null,disabled: false,}},mounted() {// 先调用一次this.updateClock()// 箭头函数不修改当前作用域下的 this 指向this.setIntVal = setInterval(() => {this.updateClock()}, 1000)},methods: {/*** 更新计时器* @result void*/updateClock() {let now = new Date().getTime()let stopTime = 0// 错误入参 处理逻辑try {stopTime = new Date(this.terminalTime).getTime()} catch (err) {console.error(err)return false}// 终止逻辑const remainingTime = stopTime - nowif (remainingTime < 1000) {clearInterval(this.setIntVal)this.setIntVal = null// 计时器 清零this.days = this.hours = this.minites = this.seconds = ['0', '0']this.disabled = trueconsole.log('时间到!')return false}// 计算 日、时、分、秒let days = parseInt(remainingTime / (24 * 60 * 60 * 1000))let hours = parseInt((remainingTime - 24 * 60 * 60 * 1000 * days) / (60 * 60 * 1000))let minites = parseInt((remainingTime - 24 * 60 * 60 * 1000 * days - 60 * 60 * 1000 * hours) /(60 * 1000))let seconds = parseInt((remainingTime -24 * 60 * 60 * 1000 * days -60 * 60 * 1000 * hours -60 * 1000 * minites) /1000)// 更新 datathis.days = this.toStringAndUnshiftZero(days)this.hours = this.toStringAndUnshiftZero(hours)this.minites = this.toStringAndUnshiftZero(minites)this.seconds = this.toStringAndUnshiftZero(seconds)},/*** 转化数字为数组,并在 头部填充 0* @params num: numnber* @result string[]*/toStringAndUnshiftZero(num) {const val = num.toString().split('')if (num < 10) {val.unshift('0')}return val},},
}
</script>

这一块根本没有什么技术含量,主要是异常数据的处理,和停止逻辑。 其实计时器清零理论上是不需要出现的,但是在测试过程中发现,会出现最后一帧为 01 的情况,就直接清零了。

animate-card

这个组件一开始考虑的很复杂,想着监听数据的变化,触发一个动画的方法,然后这个方法支持重写,提高组件的扩展性,但是时间不允许,后面又觉得不太必要。

最后选择的方案很简单,却提供了一个可以实现 css 能实现的所有效果的思路。

主要思路是通过 vue 的 transition-group 机制,将 0-9 所有的卡片都渲染好,隐藏起来,通过 v-show 来触发绑定在 transition-group 上的动画效果,从而实现动态监听数据变化的效果。

需要注意的是因为宿主项目中 引入了 animate.css,所以就直接使用 animate 的动画效果了。
有需要的,可以翻看文档 【animate.css 官方文档】进行配置。
如果直接CV这套代码的话,没有动画效果。

代码如下:

<template><div class="aimate-card"><div class="card-group" v-for="(item,idx) in val" :key="idx" :style="{'font-size': size+'px'}"><transition-group enter-active-class="animate__animated animate__bounceIn" leave-active-class="animate__animated animate__fadeOutDown"><div class="card-item" :class="{'disabled': selfDisabled}" v-for="num in 10" :key="num" v-show="item== num-1">{{num-1}}</div></transition-group></div></div>
</template><script>
export default {props: {val: {type: Array,default: () => ['0', '0'],},size: {type: Number,default: 16,},selfDisabled: {type: Boolean,default: false,},},mounted() {console.log(this.selfDisabled)},
}
</script><style lang="scss" scoped>
.aimate-card {width: auto;display: inline-block;height: 100%;.card-group {display: inline-block;position: relative;width: 40px;padding: 5px;height: 100%;vertical-align: middle;.card-item {position: absolute;background: #3a7fe4;color: #fff;width: 30px;height: 40px;top: -20px;line-height: 40px;}.disabled {background: #ccc !important;}}
}
</style>

看完代码以后很容易发现,我设计的样式其实一点都不好看,可以对 card-item 写一些前端比较炫的效果。而且动画效果也可以自定义。

项目中使用

1. 粘贴上面两个 vue 文件
2. 在业务页面中 引入并使用

使用方法如下:

<div class="vote-clock"><animate-clock :terminalTime="'2023-07-11 23:27:00'" />
</div>

Vue组件-卡片动画倒计时相关推荐

  1. 【Vue】Vue全家桶(三)Vue组件通信+Vue组件插槽+动画与过渡+使用vue-cli解决Ajax跨域问题

    1 Vue组件通信 1.1 组件间通信基本原则 不要在子组件中直接修改父组件的状态数据 数据在哪, 更新数据的行为(函数)就应该定义在哪 1.2 vue 组件间通信方式 props vue 的自定义事 ...

  2. Vue组件,动画笔记,必看

    组件: 作用: 1.组件时Vue的一个重要的特点 2,实现多人协作开发 3,通过组件划分降低开发的难度 4,实现复用,降低重复劳动 组件解释: 组件就是定义好的一功能模块 建议:多用props,少在组 ...

  3. vue\uniapp自定义活动倒计时组件

    vue\uniapp自定义活动倒计时组件 效果 调用组件时传递的 timeData的属性type_id:名称,begin_time:开始时间(时间戳)end_time:结束时间(时间戳) 组件代码 & ...

  4. vue 引入canvas_canvas动画合集Vue组件

    vue-canvas-effect canvas动画合集Vue组件 [? online demo](https://chenxuan0000.github.io/vue-canvas-effect/i ...

  5. vue组件化的理解与定义

    1. 对组件的理解 a) UI组件 项目各个页面中,会产生很多重复的功能,比如弹出层提示框,像这种纯粹非业务的UI,便成了我们所谓的UI组件,最初的前端组件也就仅仅指的是UI组件. b) 业务组件 而 ...

  6. GitChat · 前端 | Vue 组件库实践和设计

    来自 GitChat 作者:周志祥 更多IT技术分享,尽在微信公众号:GitChat技术杂谈 前言 现在前端的快速发展,已经让组件这个模式变的格外重要.对于市面上的组件库,虽然能满足大部分的项目,但是 ...

  7. ant design vue input change_ElementUI 不维护了?供我们选择的 Vue 组件库还有很多!

    1 ElementUI 近况 根据我最近的观察,得知一些关于 ElementUI 维护人员都退去的消息,这意味着什么? 这意味着后期 ElementUI 将无人维护,就算 Vue3.0 正式版出来 E ...

  8. vue组件定义、组件的切换、组件的通信、渲染组件的几种方式(标签、路由、render)...

    vue中全局的概念是什么?---就是全局定义的功能,所有实例化的vm都可以使用,  全局定义的是挂在构造函数Vue上面的,所以实例化出的对象都可以使用这个功能 1.什么是组件?---从UI的角度把页面 ...

  9. Vue 中 CSS 动画原理

    下面这段代码,是点击按钮实现hello world显示与隐藏 <div id="root"><div v-if="show">hello ...

最新文章

  1. spark_updateStateByKey
  2. 第四维、第五维空间狂想
  3. webform 跨窗体传值
  4. 雷蛇鼠标宏文件_Razer推出DeathAdder V2与Basilisk V2游戏鼠标
  5. 缓冲区溢出漏洞攻击之用户登录
  6. 【转】C++中如何区分构造函数与重载operator()得到的仿函数?
  7. 【UVA - 11729】Commando War (贪心,时间调度问题)
  8. java序列化流_java 序列化流与反序列化流
  9. 国开本科计算机应用基础操作题,2019秋国开大学计算机应用基础Windows7操作系统形考题目及答案...
  10. OpenWrt 学习网址
  11. [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)...
  12. [CTSC1999] 家园
  13. 设计模式学习与应用——单例模式
  14. nginx 完全关闭 access_log
  15. 6、Java包的命名与划分
  16. Windows bat批处理常用指令,常用指令及语法总结
  17. 微信公众号两种匹配模式(全匹配和半匹配)的区别。
  18. 2.OSGI企业应用开发-Eclipse中搭建Felix运行环境
  19. 解决Mac电脑连不上wifi的问题
  20. umi3.5微软的AD登录loginRedirect

热门文章

  1. FireFox必备插件(二)
  2. MySQL数据库11——子查询语句
  3. 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——2.4 注释及参数设置...
  4. 为视图或函数指定的列名比其定义中的列多
  5. 迁移系统:换电脑或者硬盘转移磁盘文件的方法!
  6. Allegro如何设置走线自动删除重复走线操作指导
  7. VARIANT 类型说明
  8. 水果店从哪里进货便宜,水果店都有哪些进货渠道
  9. 备份路由器配置文件到服务器,教你如何备份路由器配置文件
  10. ecshop 数据库字典