问题很常见,简单来说就是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的。