vue记录时长前端实现
Vue 前端实现时长记录功能
核心思路
通过 Date 对象或 performance.now() 记录开始/结束时间戳,计算差值后格式化为可读时间。

基础实现方案(基于 Composition API)
// 组件内
import { ref, onUnmounted } from 'vue';
const startTime = ref(null);
const duration = ref(0);
let timer = null;
// 开始计时
const startTimer = () => {
startTime.value = new Date();
timer = setInterval(() => {
duration.value = Math.floor((new Date() - startTime.value) / 1000);
}, 1000);
};
// 停止计时
const stopTimer = () => {
clearInterval(timer);
const endTime = new Date();
console.log(`总时长:${(endTime - startTime.value) / 1000}秒`);
};
onUnmounted(stopTimer); // 组件卸载时自动停止
高级封装(可复用 Hook)
// useTimer.js
import { ref, onUnmounted } from 'vue';
export default function useTimer() {
const startTime = ref(null);
const duration = ref(0);
let timer = null;
const start = () => {
startTime.value = performance.now(); // 更高精度
timer = setInterval(() => {
duration.value = Math.floor((performance.now() - startTime.value) / 1000);
}, 1000);
};
const stop = () => {
clearInterval(timer);
return (performance.now() - startTime.value) / 1000;
};
onUnmounted(stop);
return { duration, start, stop };
}
组件中使用:

const { duration, start, stop } = useTimer();
时间格式化显示
// utils/formatTime.js
export function formatDuration(seconds) {
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
return `${h}h ${m}m ${s}s`;
}
持久化存储方案
结合 localStorage:
// 存储记录
localStorage.setItem('lastDuration', duration.value);
// 读取记录
const lastDuration = localStorage.getItem('lastDuration');
注意事项:
- 精度选择:
performance.now()比Date更适合短时长测量 - 内存泄漏:务必在组件卸载时清除定时器
- 暂停功能:可通过记录累计时间实现
完整组件示例
<template>
<div>
<button @click="start">开始</button>
<button @click="stop">停止</button>
<p>已持续:{{ formattedTime }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import useTimer from './useTimer';
import { formatDuration } from './utils/formatTime';
const { duration, start, stop } = useTimer();
const formattedTime = ref('0s');
watch(duration, (val) => {
formattedTime.value = formatDuration(val);
});
</script>






