问题很常见,简单来说就是A,B,C三个页面。
A>B不缓存,C>B需要缓存。
想着记得之前网上看过,就一顿操作。
在路由里面加上了
{
path: '/b',
name: 'B',
component: B,
meta:{
keepAlive:true
}
}
在app.vue写了
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
A页面写了
beforeRouteLeave(to, from, next) {
to.meta.keepAlive = false;
next();
}
C页面写了
beforeRouteLeave(to, from, next) {
to.meta.keepAlive = true;
next();
}
以为没事了。结果一测试发现。
第一次A>B>C,之后再返回B的话,不会被缓存。
从B到A,之后到B,B没被缓存,表现正常,之后点击C,这个时候从C返回,得到的是一开始B的缓存。
折腾半天,发现还是解决不掉。
最后终于发现一个完美的方法。
利用include,动态添加"B"
步骤如下:
1、在app.vue下增加keep-alive
<keep-alive :include="catchList">
<router-view></router-view>
</keep-alive>
这里的catchList,是vuex维护的需要缓存的组件名的一个数组
2、在路由中加入
router.beforeEach((to, from, next) => {
if (to.name === 'B') {
store.commit('keepAlive', 'B')
}
next()
})
3、在b.vue中加入
beforeRouteLeave (to, from, next) {
if (to.name !== 'C') {
this.$store.commit('noKeepAlive')
}
next()
}
备注,在vuex中mutation是
keepAlive(state, component) {
!state.catchList.includes(component) &&
state.catchList.push(component)
},
noKeepAlive(state) {
state.catchList = []
}
大致的原理是,只要是B的组件,都缓存。只有当从B>A的时候,才让B不缓存。
亲测同原理,但是meta.keepAlive会出现其他bug
所以,目前来看,能用的方法,其实只有这一种。
网上大量的设置meta的方法,亲测都存在问题,不知道是都没注意到还是都是copy的。
第二天更新
今天看了下keep-alive源码,证实了meta.keepAlive=true这种方法,解决不了条件缓存问题
原因:在keep-alive源码中,include和exclude是被watch的,当发生变化时,keep-alive会去校验cache里是否匹配,匹配不上的会被删除。也就是说,官方是为这种情况做了处理的。而meta这种方法,因为没有存在某种类似于watch的方法,导致这种方法天然是和实际cache里面的内容有出入的,所以可定会存在各种奇怪的bug。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。