问题处理一——在应用实例创建时加入路由监听
问题描述:不关闭浏览器和在不结束当前VUE应用实例之前,再次重新进入页面时,发现页面没有重新请求接口,即,不刷新页面不重新请求接口(接口本身会在mounted中进行调用)。而实际应用中请求头中的部分参数已经发生改变,需要重新请求来刷新页面数据。
原因分析:App.vue
中引入了<keep-alive>
组件,由于不携带参数的情况下,本质上是对当前组件实例的重用,也就是路由未发生变化。因此不会刷新当前组件,不会调用created()
、mounted()
等生命周期中的函数。
<keep-alive>
<router-view :key="$route.fullPath"></router-view>
</keep-alive>
解决方案:在跳转页面时加上时间戳,选择在全局路由前置守卫处加入时间戳,后续如有需要缓存的页面,可在路由配置处添加参数控制<keep-alive>
组件,是否进行缓存。
router.beforeEach((to, from, next) => {
let timestamp = Date.now()
if (!to.query.t){
next({...to, query: {...to.query, t: timestamp}})
} else {
next()
}
})
问题处理二——全局路由添加时间戳
问题描述:一开始想在全局前置路由中添加时间戳,因此写了以下代码,报错:Maximum call stack size exceeded
router.beforeEach((to, from, next) => {
let timestamp = Date.now()
next({...to, query: {...to.query, t: timestamp}})
})
原因分析:
1.在 router.beforeEach 钩子函数中,对 to 对象进行了过度修改,导致钩子函数不断被触发,从而导致调用栈溢出。
2.在 next 函数中,重复调用了 next({…to, query:{t: Date.now()}})。这会导致路由重复触发 beforeEach 钩子函数,从而陷入无限循环。
解决方法:
1.使用一个标志位来跟踪是否已经添加了时间戳,从而避免重复添加
router.beforeEach((to, from, next) => {
if (!to.query.t) {
next({ ...to, query: { ...to.query, t: Date.now() }})
} else {
next()
}
})
2.将时间戳的添加逻辑放在 router.afterEach 钩子函数中,而不是 beforeEach。这样可以确保只在导航完成后添加时间戳,避免无限循环。
router.afterEach((to, from) => {
to.query.t = Date.now()
})
3.除此之外还需要注意,在修改 to 对象时,只修改必要的部分,而不是完全覆盖整个对象。
router.beforeEach((to, from, next) => {
next({ ...to, query: { ...to.query, t: Date.now() }})
})