vue的缓存页面是使用keep-alive实现,那如果要实现在某些指定页面之间切换才缓存页面要怎么实现呢?
比如现在有A,B,C三个页面,B页面是一个中间处理页面,A,C是独立的页面,要实现A --> B的时候缓存,这样才B页面返回到A页面时,A页面就不会刷新,其他情况的页面跳转,都要刷新重新加载,比如C --> A的时候就是正常的跳转,会刷新页面。
实现这个效果,我使用的是组件内的路由守卫+vuex实现
先说几个点:
- 组件内的路由守卫:
// 在进入页面前执行,这个函数内拿不到this,需要在next的回调里面操作,代替我们平常使用的this
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$store.....
})
},
// 在离开页面前执行
beforeRouteLeave (to, form, next) {
next()
}
但并不是所有vue组件都有路由守卫,需要在router中注册了的组件才会有路由守卫,也就是下面图片中圈出来的组件:
image.png
- keep-alive的include属性
keep-alive的include属性指定需要缓存的页面,可以是字符串,也可以是数组,include填写的是组件的name属性,而不是路由的name属性,所以用include来缓存页面,需要给你的vue组件写上name属性
当给include传递一个空字符串的时候,会把所有页面都进行缓存,传递一个空数组的时候就不会缓存页面,效果是相反的。
接下来实现一开始说的效果,因为在路由守卫中拿到的是route的信息,所以将组件的name属性和在路由的meta中对应上
路由:
{
path: '/a',
component: A,
meta: {componentName:'A'}
},
{
path: '/b',
component: B,
meta: {componentName:'B'}
},
{
path: '/c',
component: C,
meta: {componentName:'C'}
}
vuex:
state:{
keepAlivePage: []
},
mutations:{
setKeepAlivePage (state, data) {
state.keepAlivePage = data
}
}
在根组件:
<keep-alive :include="keepAlivePage">
<router-view></router-view>
</keep-alive>
computed: {
keepAlivePage () {
return this.$store.state.getKeepAlivePage
}
}
A组件:
name: 'A',
// 在进入页面前将A页面存到缓存中
beforeRouteEnter (to, from, next) {
next(vm => {
// 此时的to就是A的路由
vm.$store.commit('setKeepAlivePage', [to.meta.componentName])
})
},
beforeRouteLeave (to, form, next) {
// 判断是不是到B页面,如果不是,就取消缓存
if (to.path != '/b') {
this.$store.commit('setKeepAlivePage', [])
}
next()
}
到这里所说的缓存效果就实现了,可能会有疑问,为什么要用beforeRouteEnter 这个守卫,为什么不在beforeRouteLeave 这个页面离开之前的函数里面加入缓存,判断是进入B页面时加入缓存不就行了吗?因为keep-alive缓存页面是要在进入页面之前就缓存,如果在beforeRouteEnter 再将页面加入缓存数组,就会出现第一次页面不缓存的情况,我也是尝试了才发现,如果你有更好的实现方法(一定是有的),欢迎指教哦。
网友评论