本文共 2715 字,大约阅读时间需要 9 分钟。
在最近的开发中,设计有A、B、C三个页面,试想这样一个场景需求:
keep-alive
组件内的守卫 - beforeRouteLeave
this
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, // a meta field meta: { keepAlive: true } } ] } ]})复制代码
class Home extends Vue { get keepAlive () { // 获取当前路由的元信息中的keepAlive字段 return this.$route.meta.keepAlive } private render () { return ({ !this.keepAlive &&) } } export default Home复制代码} { this.keepAlive && }
由于现在组件的keep-alive是动态根据路由元信息中的keepAlive字段进行动态使用的,所以只要动态改变对应路由元信息的keepAlive字段就可以实现动态缓存。
beforeRouteLeave (to: any, from: any, next: any) { // 导航离开该组件的对应路由时调用 // 判断是否是去往页面 C if (to.name !== 'C') { // 不是去 C 页面,不缓存 from.meta.keepAlive = false } else { // 是去 C 页面,缓存 from.meta.keepAlive = true } next()}复制代码
bug:首次去C页面,再返回B页面,B并没有缓存,第二次再进入C页面,B页面缓存,且进A页面并不能清除B页面的缓存
beforeRouteLeave (to: any, from: any, next: any) { // 导航离开该组件的对应路由时调用 // 判断是否是去往页面 C if (to.name !== 'C') { // 不是去 C 页面,不缓存 this.$destroy() } next()}复制代码
bug:销毁之后永远不会被缓存
// 操作指定name的路由的元信息private changeKeepAlive (parentName: string, name: string, keepAlive: boolean) { // @ts-ignore this.$router.options.routes.map((item: any) => { if (item.name === parentName) { item.children.map((a: any) => { if (a.name === name) { a.meta.keepAlive = keepAlive } }) } })}beforeRouteLeave (to: any, from: any, next: any) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` if (to.name === 'C') { this.changeKeepAlive('Home', 'B', true) } else { this.changeKeepAlive('Home', 'B', false) } next() }复制代码
经测试,这种解决方案就不会出现方案一的bug
BY--LucaLJX ()
作者:LucaLJX 链接:https://juejin.im/post/5c1cc517e51d45778a5c72c6 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。