动态倒计时在 Vue 3 中的实现

目录

  • 1. Demo
  • 2. 实战Demo
  • 3. 拓展Demo

1. Demo

给一版初始的Demo,在给一版实战中的Demo

基本知识点:

  • Vue 3 的响应式原理:Vue 3 使用 reactive 和 ref 创建响应式数据,数据的变化会自动触发视图更新
  • setup 函数:Vue 3 引入了 Composition API,其中的 setup 函数是组件逻辑的入口
  • watch 侦听器:用于侦听响应式数据的变化,在倒计时场景中可以用于监听时间的变化
  • 生命周期钩子:如 onMounted 和 onUnmounted 用于在组件挂载和销毁时启动和清理倒计时
  • setInterval 和 clearInterval:用于每隔一段时间执行倒计时任务

Demo:

<template><div><table><thead><tr><th>任务名称</th><th>剩余时间</th></tr></thead><tbody><tr v-for="task in tasks" :key="task.id"><td>{{ task.name }}</td><td>{{ task.remainingTime }} 秒</td></tr></tbody></table></div>
</template><script setup>
import { reactive, onMounted, onUnmounted } from 'vue';const tasks = reactive([{ id: 1, name: '任务A', remainingTime: 60 },{ id: 2, name: '任务B', remainingTime: 120 },{ id: 3, name: '任务C', remainingTime: 180 },
]);let intervalId;onMounted(() => {intervalId = setInterval(() => {tasks.forEach(task => {if (task.remainingTime > 0) {task.remainingTime -= 1;}});}, 1000);
});onUnmounted(() => {clearInterval(intervalId);
});
</script>

2. 实战Demo

本身倒计时的某一列时间是固定的,那就不需要通过后端来获取动态数据,只需要基于appointmentEndTime和当前时间来计算倒计时。对于超过当前时间的数据,可以直接显示“已结束”或其他提示

以下是基于Vue 3的倒计时实现方式,重点是如何根据appointmentEndTime与当前时间来动态更新表格的倒计时列

  • appointmentEndTime 固定:你可以直接在表格数据中使用固定的时间戳。
  • 倒计时逻辑:通过setInterval每秒更新一次倒计时,但如果appointmentEndTime已经过期,就不再更新。
  • 无须请求后端:无需额外API请求,直接使用appointmentEndTime进行计算
<template><div><el-table :data="tableData" style="width: 100%"><!-- 审核时间列 --><el-table-columnlabel="审核时间"align="center"prop="appointmentReviewTime":formatter="dateFormatter"width="170px"/><!-- 还柜时间列 --><el-table-columnlabel="还柜时间"align="center"prop="appointmentEndTime":formatter="dateFormatter"width="170px"/><!-- 倒计时列 --><el-table-column label="倒计时" align="center" width="170px"><template #default="scope"><span>{{ formatCountdown(scope.row.appointmentEndTime) }}</span></template></el-table-column></el-table></div>
</template><script>
import { ref, onMounted, onBeforeUnmount } from 'vue';export default {setup() {// 表格数据,appointmentEndTime 是固定的时间const tableData = ref([{appointmentReviewTime: '2024-09-20 12:00:00',appointmentEndTime: '2024-09-20 14:00:00' // 固定时间},{appointmentReviewTime: '2024-09-21 15:00:00',appointmentEndTime: '2024-09-21 17:00:00' // 固定时间}]);// 倒计时格式化函数const formatCountdown = (endTime) => {const now = new Date().getTime();const endTimestamp = new Date(endTime).getTime();const remainingTime = endTimestamp - now;// 如果已过期,返回 "已结束"if (remainingTime <= 0) {return '已结束';}const hours = Math.floor(remainingTime / (1000 * 60 * 60));const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);return `${hours}小时 ${minutes}分钟 ${seconds}`;};// 使用 setInterval 动态更新倒计时const intervalId = ref(null);onMounted(() => {intervalId.value = setInterval(() => {// 强制触发视图更新tableData.value = [...tableData.value];}, 1000);});// 清除计时器onBeforeUnmount(() => {clearInterval(intervalId.value);});return {tableData,formatCountdown};}
};
</script>

在这里插入图片描述

如果不会出现自动更新视图的,需要排查下浏览器的终端是否会有输出异常

实战中的Bug:(错误信息 queryParams.value is not iterable 表示在某处尝试遍历或解构了queryParams,但是它不是可迭代的对象,确保queryParams是一个对象或数组,不能将非迭代对象进行迭代操作)
在这里插入图片描述

3. 拓展Demo

appointmentEndTime这个是timestamp时间,也就是设定的未来时间
但是我要已过期,或者超过当前时间的 都显示 重新预约

那么只需要在超过当前时间或已过期的情况下显示“重新预约”

  1. 修改 formatCountdown 函数
    在 formatCountdown 函数中添加一个返回值,用于标记该时间是否已经过期
const formatCountdown = (endTime) => {const now = new Date().getTime();const endTimestamp = new Date(endTime).getTime();const remainingTime = endTimestamp - now;// 如果已过期,返回 "已过期" 并标记为需要重新预约if (remainingTime <= 0) {return { text: '已过期', isExpired: true };}const hours = Math.floor(remainingTime / (1000 * 60 * 60));const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);// 分时秒的格式化return { text: `${hours}小时 ${minutes}分钟 ${seconds}`, isExpired: false };
};
  1. 修改模板逻辑

使用 formatCountdown 函数的返回值来判断是否显示 “重新预约”

<el-table-column label="还柜剩余时间" align="center" width="155px"><template #default="scope"><span>{{ formatCountdown(scope.row.appointmentEndTime).text }}</span></template>
</el-table-column><el-buttonlinktype="primary"@click="showRejectionReason(scope.row.id)"v-if="scope.row.appointmentEndTime !== null && formatCountdown(scope.row.appointmentEndTime).isExpired"v-hasPermi="['dangerous:appointment-commission:query']"
>重新预约
</el-button>

在这里插入图片描述

为了在等于当前时间点的时候触发后端请求

可以修改倒计时的函数如下:

// 倒计时格式化函数
const formatCountdown = (endTime,id) => {const now = new Date().getTime();const endTimestamp = new Date(endTime).getTime();const remainingTime = endTimestamp - now;// 设置一个容忍时间范围(例如,1秒)const tolerance = 1000; // 1秒// 当时间接近到达时,发送请求到后端更新状态if (remainingTime <= tolerance && remainingTime > 0) {console.log(1); // 确保能够输出}// 如果已过期,返回 "已过期" 并标记为需要重新预约if (remainingTime < 0) {return { text: '已过期', isExpired: true };}const hours = Math.floor(remainingTime / (1000 * 60 * 60));const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);// 分时秒的格式化return { text: `${hours}小时 ${minutes}分钟 ${seconds}`, isExpired: false };
};

以上的函数需要注意的点如下:

由于时间的精确性和计算方式,remainingTime 很少会正好等于 0。即使时间点非常接近,由于毫秒级的差异,可能导致 remainingTime 不完全等于 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148729.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

​智慧铜矿厂综合管控平台,智慧矿山数字孪生

随着矿山行业的不断发展&#xff0c;传统的管理方式已经无法满足现代铜矿高效、安全、环保和精细化管理的需求&#xff0c;因此&#xff0c;构建一个综合管控平台变得尤为必要。HT 铜矿综合管控平台应运而生&#xff0c;通过信息化和智能化手段&#xff0c;整合采矿、选矿、冶炼…

【包教包会】CocosCreator3.x框架——音频模块(无需导入、无需常驻节点)

下载地址&#xff1a;AudioDemo3.x: CocosCreator3.x框架——音频模块 注意事项&#xff1a; 1、gi.musicPlay、gi.soundPlay是同步函数&#xff0c;使用前必须先将音频加载到缓存 Demo通过SceneLoading实现了一个极简的Loading页面&#xff0c;将音频全部加载后进入游戏&…

Vue学习文档

文章目录 一、Vue 简介1、官网2、作者和版本3、定义4、特点5、Vue 的周边库二、Vue 安装使用1、CDN 引入2、下载后引入3、命令行工具 (CLI)三、入门案例四、MVVM模型1、MVVM 模型2、Vue 与 MVVM 模型五、Vue 基本使用1、文本插值(掌握)-text2、属性插值(掌握 )-bind3、Clas…

【Python】Spyder:科学 Python 开发环境

在数据科学和科学计算领域&#xff0c;Python 已经成为了一个不可或缺的工具。为了提高开发效率和改善编程体验&#xff0c;一个功能强大且用户友好的开发环境是必需的。Spyder&#xff08;Scientific Python Development Environment&#xff09;正是这样一个为科学计算和数据…

数据结构-线性表的单链式存储结构图解及C语言实现

概念 链式存储&#xff1a;结点在存储器中的位置是任意的&#xff0c;即逻辑相邻的数据元素在物理上不一定相邻 链式存储结构也称非顺序映像或链式映像 图解 链式存储结构中结点一般有两个部分组成&#xff0c;即数据域(data)和指针域&#xff0c;数据域是用于存放数据的&…

振弦式轴力计 轴向力仪器钢支撑轴力计 清易让选择不再迷路

产品概述 振弦式轴力计是一种用于测量轴向力的仪器。它通过测量振弦的频率变化来计算轴向力的大小。当轴向力作用在弹性元件上时&#xff0c;振弦的张力会发生变化&#xff0c;从而导致振弦的频率发生变化。电磁线圈用于驱动振弦并测量其频率。信号处理单元则用于将频率信号转…

Anthropic谋求新一轮融资 估值或达400亿美元

&#x1f989; AI新闻 &#x1f680; Anthropic谋求新一轮融资 估值或达400亿美元 摘要&#xff1a;美国AI初创公司Anthropic正在与投资者洽谈新一轮融资&#xff0c;估值可能达到300至400亿美元&#xff0c;约为今年初融资估值的两倍。Anthropic依靠其生成式AI聊天机器人Cla…

LNK2019:无法解析的外部符号 “class std::basic_ostream ...(template 的声明)

文章目录 一、问题&#xff1a;二、解决&#xff1a;1. 问题2. 解释① 类模板② 函数模板 一、问题&#xff1a; 今天在实现 vector 时&#xff0c;发现出现了一个错误&#xff1a; 它说&#xff0c;不认识 ostream&#xff0c;我在重载<< 符号时&#xff0c;使用了 ost…

7.ChatGPT与SEO - 优化内容策略【7/10】

引言 在当今的数字化时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已成为数字营销中不可或缺的一部分。它不仅帮助企业提高在线可见性&#xff0c;还直接影响着网站的流量、品牌知名度和最终的销售转化。SEO通过优化网站内容和结构&#xff0c;使其在搜索引擎结果…

【Python】多个dataframe存入excel的不同的sheet表里,而不会被覆盖的方法

我发现&#xff0c;我原来用的多个工作簿存入的方法&#xff0c;发现不太可行了。当使用for循环的时候&#xff0c;原来的sheet 会被新的表给覆盖&#xff0c;后来我找到一种新的方法&#xff1a; with pd.ExcelWriter(file_name ) as writer:Table.to_excel(writer, sheet_na…

JAVA无缝沟通全球国际版多语言语聊系统小程序源码

无缝沟通全球 —— 国际版多语言语聊系统 &#x1f30d;【开篇&#xff1a;跨越语言障碍&#xff0c;与世界无缝对话】&#x1f30d; 在这个全球化的时代&#xff0c;你是否渴望与世界各地的朋友无缝交流&#xff0c;却常常被语言的隔阂所困扰&#xff1f;别担心&#xff0c;今…

振弦式渗压计智慧水利工程 适用恶劣环境有保障

产品概述 振弦式渗压计适合埋设在水工建筑物和基岩内&#xff0c;或安装在测压管、钻孔、堤坝、管道或压力容器中&#xff0c;以测量孔隙水压力或液位。主要部件均采用特殊钢材制造&#xff0c;适合在各种恶劣环境中使用。特殊的稳定补偿技术使传感器具有极小的温度补偿系数。…

Adobe Photoshop 2024 v25.12 (macOS, Windows) 发布下载 - 照片和设计软件

Adobe Photoshop 2024 v25.12 (macOS, Windows) - 照片和设计软件 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、Lightroom Classic、Media Encoder、Photoshop、Premiere Pro、Adobe XD…

CSS02-字体属性、文本属性

一、字体属性 CSS Fonts(字体)属性用于定义字体系列、大小、粗细、和文字样式(如斜体)。 1-1、font-family属性 当font-family有多个值的时候&#xff0c;代码会依次查找当前系统中存在哪种字体&#xff0c;有则使用&#xff0c;没有则查找下一个字体。 1-2、font-size属性 1-3…

wpf中如何访问控件和生成使用事件?

实际上对于初次使用wpf的同学来说&#xff0c;尤其是有winform编程经验的童鞋来说&#xff0c;最需要解决的就是快速掌握访问控件的方法以及生成和使用事件。这样才能让页面具有最起码的交互性。下面我们来分别讲述。 文章原出处&#xff1a;https://blog.csdn.net/haigear/ar…

双链表和循环链表的各种基本运算的算法(数据结构作业03)

双链表 目的&#xff1a;双链表的存储结构和掌握双链表中各种基本运算算法的设计 内容&#xff1a;编写一个程序dlinkst.cpp,实现双链表的各种基本运算和整体建表算法&#xff0c;双链表的元素类型Elem Type为int并在此基础上设计一个程序。 (1)初始化双链表h。 (2)依次采用尾…

电动车无钥匙一键启动‌系统应用

电动车无钥匙一键启动‌是一种便捷的启动方式&#xff0c;它允许车主在不使用传统钥匙的情况下启动车辆。这种启动方式通常依赖于无线射频识别&#xff08;RFID&#xff09;技术&#xff0c;通过车主随身携带的智能卡里的芯片感应自动开关门锁。当车主走近车辆时&#xff0c;门…

日志系统扩展一:日志落地数据库:MySQL、SQLite3

日志系统扩展一&#xff1a;日志落地数据库&#xff1a;MySQL、SQLite3 一、设计1.怎么落地2.落地的具体设计3.表的设计1.MySQL2.SQLite3 二、数据库访问Helper的实现1.需要事务&#xff0c;但是无需回滚&#xff0c;如何理解&#xff1f;1.需要事务2.无需回滚 2.SqliteHelper1…

ICM20948 DMP代码详解(40)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;39&#xff09; 上一回继续解析inv_icm20948_set_slave_compass_id函数&#xff0c;解析到第5段代码inv_icm20948_setup_compass_akm函数&#xff0c;本回解析接下来的代码。为了便于理解和回顾&#xff0c;再次贴出该…

77、Python之函数式编程:一文搞懂functools模块的核心应用

引言 Python作为一种支持多范式的编程语言&#xff0c;除了在“一切皆对象”的理念支持下的&#xff0c;函数对象也是一等公民、各种高阶函数的自然实现、lambda表达式快速编写纯函数之外。还有一个内置的模块functools&#xff0c;能够更好地支持我们在Python中应用函数式编程…