问题描述
项目背景:项目是spa单页面应用,点击上方大菜单会进行路由跳转,这个时候实际展示的页面文件会发生变化,同时每个页面有可能会有左侧的小菜单,点击小菜单同时会发生路由跳转,但是这个时候展示的页面文件是同一个,只是通过不同的路由去获取不同的数据重新渲染当前页面。
问题一:点击左侧小菜单时发生了路由跳转,但是页面没有重新渲染。
发现这个问题后,判断是路由更新时没有通知到组件,但是页面代码里明明有做路由相关的响应式变量,dom里也有引用,为什么数据变化了但是页面没有更新呢,难道vue给的承诺是假的?由此引申了问题二。
问题二:vue监听路由变化的响应式失效。
解决问题
首先来说第一个问题,解决思路很简单,就是在路由跳转的时候重新加载组件嘛,只需要给router-view添加一个和路由变化时相关的key就可以了,这样在渲染虚拟dom的时候算法就会判断两次的组件是有区别的,虽然看起来很简单,但是作者一开始没想到这个地方,使用了状态管理器,自定义事件等等方法,现在想来这些方法有些还是能成功奏效的,但是由于第二个问题的存在,这些问题都失败了。
<router-view :key="router.currentRoute.value.fullPath"></router-view>
接下来是第二个问题,其实也很简单,我这里使用响应式监听的是router.currentRoute.value.fullPath,但是router.push方法会直接改变currentRoute对象,这样使用ref响应对象里的属性就会失效,最后在公司大佬的指导下改用了computed,虽然是成功了,但是暂时还不太清楚原理,暂时先把解决问题的方法记录分享一下吧。
//let cRoute = ref(router.currentRoute.value.fullPath)
let cRoute = computed(() => {
return router.currentRoute.value.fullPath;
});