当路由到某个组件时,由于组件会复用,所以生命周期函数不会再次执行,
如果这个组件是模板组件,靠传入不同数据来显示的.那么,可能会发生参数变化了但页面数据却不变化.
问题
假如有个组件 info.vue
路由path如下
1. /user/info/23 // 23是参数,下面34也是参数
2. /user/info/34
希望通过参数来刷新组件页面数据.刷新数据的方法在Vue生命周期函数的created方法里调用.
当改变参数时,页面并没有变化.因为,路由只是参数变化了,path并没变化,组件还是这个info.vue组件.
此时,组件复用,生命周期函数不再执行,所以刷新数据的方法也就没机会执行了.
研究
官网上推荐使用watch,监控路由变化,将取数据方法在watch中调用,
或者是 beforeRouteUpdate 这个路由生命周期函数,https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E7%BB%84%E4%BB%B6%E5%86%85%E7%9A%84%E5%AE%88%E5%8D%AB
经过测试,当路由的参数变化之后,数据刷新了,
但是出了个新问题,就是当路由改变时,再回到改变前的路由时,又不刷新了.
假设当前路由是
/user/info/34
跳到路由
/home
然后再跳回来到
/user/info/34
这里,页面又不动了.
经过研究发现,配合使用这两个路由周期函数,能解决这问题
beforeRouteEnter 和 beforeRouteUpdate
前者在进入路由所在组件时(路由发生变化)执行,
后者在路由的参数变化时执行
在这两个方法里执行刷新数据,两者时机对应两种切换路由操作.经过实践,要两者配合才行.否则会有bug.
如果只用其一,那么,当路由不变,只变参数时,就刷新不了列表
如果只用其二,那么,当路由地址变化时,就刷新不了列表
最后,没有使用watch,而是使用了下面的方法
总结
这两个路由周期函数的时机正好是在路由不变参数变化时执行和路由变化时执行.所以能解决上述BUG.
// 这个方法不用调用this,因为此时机组件还没生成,所以无this
// 要调用刷新数据方法时,需要写在next回调里,
// next是在组件生成后会调用
beforeRouteEnter(to: any, from: any, next: any) {
next((vm: any) => {
vm.updateList(to.params.id);
});
} // 这个方法是路由不变,只变参数时执行
private beforeRouteUpdate(to: any, from: any, next: any) {
this.updateList(to.params.id);
next();
} // 更新数据方法
private updateList(userId: string) { }