vue记录时长前端实现
Vue 前端实现时长记录功能
核心思路
通过 Vue 的响应式数据结合浏览器 API(如 Date 对象或 performance.now())实现计时功能,需考虑开始、暂停、继续和重置等操作。
实现步骤
1. 定义响应式数据
在 Vue 组件中定义计时相关数据:
data() {
return {
startTime: null, // 开始时间戳
elapsedTime: 0, // 累计时长(毫秒)
isRunning: false, // 是否正在计时
timerInterval: null // 定时器引用
};
}
2. 核心计时逻辑
使用 setInterval 更新当前时长:
methods: {
startTimer() {
if (this.isRunning) return;
this.isRunning = true;
this.startTime = Date.now() - this.elapsedTime;
this.timerInterval = setInterval(() => {
this.elapsedTime = Date.now() - this.startTime;
}, 10); // 10ms 更新一次,提高精度
},
pauseTimer() {
clearInterval(this.timerInterval);
this.isRunning = false;
},
resetTimer() {
clearInterval(this.timerInterval);
this.isRunning = false;
this.elapsedTime = 0;
}
}
3. 格式化显示时长
将毫秒转换为 HH:MM:SS 格式:
computed: {
formattedTime() {
const date = new Date(this.elapsedTime);
return [
date.getUTCHours().toString().padStart(2, '0'),
date.getUTCMinutes().toString().padStart(2, '0'),
date.getUTCSeconds().toString().padStart(2, '0')
].join(':');
}
}
4. 模板绑定
在模板中绑定数据和事件:
<template>
<div>
<div>当前时长:{{ formattedTime }}</div>
<button @click="startTimer" :disabled="isRunning">开始</button>
<button @click="pauseTimer" :disabled="!isRunning">暂停</button>
<button @click="resetTimer">重置</button>
</div>
</template>
高级优化
持久化记录
使用 localStorage 保存计时状态,避免页面刷新丢失:
mounted() {
const savedTime = localStorage.getItem('elapsedTime');
if (savedTime) this.elapsedTime = parseInt(savedTime);
},
watch: {
elapsedTime(newVal) {
localStorage.setItem('elapsedTime', newVal.toString());
}
}
性能优化
替换 Date.now() 为更高精度的 performance.now():
this.startTime = performance.now() - this.elapsedTime;
this.timerInterval = setInterval(() => {
this.elapsedTime = performance.now() - this.startTime;
}, 10);
多组件复用
通过 Mixin 或自定义 Hook 复用逻辑(Vue 3):

// useTimer.js (Composition API)
import { ref, computed, onUnmounted } from 'vue';
export default function useTimer() {
const elapsedTime = ref(0);
const isRunning = ref(false);
let startTime = null;
let timerInterval = null;
const start = () => {
if (isRunning.value) return;
isRunning.value = true;
startTime = Date.now() - elapsedTime.value;
timerInterval = setInterval(() => {
elapsedTime.value = Date.now() - startTime;
}, 10);
};
// 其他方法(pause/reset)...
onUnmounted(() => clearInterval(timerInterval));
return { elapsedTime, isRunning, start };
}
注意事项
- 内存泄漏:组件销毁时需清除定时器(
beforeUnmount钩子)。 - 精度选择:根据需求调整
setInterval的间隔(如 1s 级更新可降低性能消耗)。 - 跨标签页同步:通过
BroadcastChannelAPI 实现多标签页状态同步。






