用 watcheffect 实现视频进度条与 url 同步,核心是监听 currenttime 变化并防抖更新 url 参数 ?t=,页面加载时解析 t 并在元数据就绪后恢复播放位置,拖拽时通过 seeking/seeked 事件暂定同步以避免冲突。

用 watchEffect 实现视频进度条与 URL 同步,核心是监听播放时间变化,自动更新 URL 的查询参数(如 ?t=123),并在页面加载时读取该参数恢复播放位置。关键在于避免循环触发、处理精度和用户交互干扰。
监听播放时间并同步到 URL
在组件 setup 中使用 watchEffect 监听视频元素的 currentTime,当它变化时调用 replaceState 或 pushState 更新 URL,不触发页面刷新:
- 优先用
replaceState避免历史记录堆积,尤其在频繁更新时 - 添加防抖(如
setTimeout延迟 500ms 提交)防止 URL 过度写入 - 只在播放中(
video.playing)或非拖拽状态下更新,避免和用户手动拖动冲突 - 格式化时间为整数秒,例如
Math.round(video.currentTime),减少冗余参数
从 URL 恢复播放进度
页面初始化时解析 URL 中的 t 参数,并设置视频起始时间:
- 使用
useRoute()(Vue Router)或new URL(location.href).searchParams.get('t')获取参数 - 在
onMounted中设置video.currentTime = t,但需确保视频已加载元数据(监听loadedmetadata事件或加await video.play()后暂停) - 若视频尚未 ready,暂存时间值,在
canplay或loadedmetadata后再应用
处理用户拖动与状态竞争
用户拖动进度条时,会主动修改 currentTime,此时应暂停自动同步,防止 URL 被错误覆盖:
- 监听
seeking和seeked事件,用 ref 标记“用户正在拖动”状态 - 在
watchEffect内部跳过更新:若isSeeking.value为 true,则不执行 URL 写入 -
seeked触发后重置标记,并可立即同步一次 URL,确保最终位置准确
保存播放状态(暂停/播放)可选增强
仅同步时间不够,用户可能希望刷新后继续播放而非暂停:
- URL 中增加
&playing=true参数,配合video.paused状态 - 恢复时若
playing=true且视频已就绪,调用video.play().catch(() => {})(静音或用户手势限制下可能失败) - 更稳妥做法:只恢复时间,播放状态由用户显式操作决定,避免自动播放策略拦截










