路由守卫本身不直接记录停留时间,但可配合生命周期钩子和时间戳实现轻量级埋点:进入页面时记录开始时间,离开时计算差值并上报;需结合全局守卫与组件钩子,并处理keep-alive、阈值过滤、页面卸载补报等健壮性逻辑。

路由守卫本身不直接记录停留时间,但可以配合生命周期钩子和时间戳,实现轻量级页面停留埋点。核心思路是:进入页面时记下开始时间,离开页面(或切换路由)时计算差值并上报。
利用 beforeEach + afterEach 记录进出时间
在全局前置守卫中记录目标页面的进入时间,在全局后置守卫中计算上一个页面的停留时长(注意:afterEach 没有 next,不能拦截,适合纯记录)。
- 在 beforeEach 中保存即将进入页面的路径和当前时间(
performance.now()更精确,或Date.now()) - 在 afterEach 中读取上一次进入时间,结合当前时间算出前一个页面的停留时长,并触发埋点上报
- 需额外维护一个变量(如
lastEnterTime和prevRoutePath),避免跨 tab 或刷新丢失状态
结合组件生命周期更精准(推荐)
单页应用中,用户可能不跳转路由但切换了视图(如 Tab 切换、弹窗、动态组件渲染)。此时仅靠路由守卫不够,应补充组件级控制:
- 在页面组件的 onMounted 中记录
startTime = Date.now() - 在 onBeforeUnmount 中计算
duration = Date.now() - startTime并上报 - 对 keep-alive 缓存组件,需监听 activated / deactivated 钩子,分别处理可见/不可见时段
防误报与健壮性处理
真实场景中需过滤无效行为,避免噪声数据干扰分析:
- 设置最小停留阈值(如 ≥500ms),忽略快速跳转或误点
- 页面卸载前(
beforeunload)补报一次,防止用户直接关页导致数据丢失 - 对 SPA 内部跳转,确保每次新页面都重置计时;对非 Vue 路由跳转(如 a 标签、window.location),需单独监听
- 上报建议用 sendBeacon,保障页面关闭时仍能发出请求
简易代码示意(Vue Router 4 + Composition API)
在 main.ts 或路由配置后:
let lastEnterTime = 0
let prevPath = ''
<p>router.beforeEach((to) => {
if (prevPath && lastEnterTime) {
const duration = Date.now() - lastEnterTime
if (duration > 500) {
reportPageStay(prevPath, duration) // 自定义上报函数
}
}
prevPath = to.path
lastEnterTime = Date.now()
})</p><p>// 组件内(setup)
onMounted(() => {
startTime = Date.now()
})
onBeforeUnmount(() => {
const duration = Date.now() - startTime
if (duration > 500) reportPageStay(route.path, duration)
})</p>









