路由配置
keepAlive访问这些页面需要缓存组件
{
path: 'xxx',
name: 'xxx',
component: () => import('xxx'),
meta: {
title: 'xxx',
keepAlive: ['路由name', 'b'],
},
}
vuex设置
state: {
keepAliveIncludes:[]
},
mutations: {
//设置缓存
SET_KEEPALIVEINCLUDES:(state,data)=>{
const has = state.keepAliveIncludes.find(i=>i.path === data.path)
if(!has){
state.keepAliveIncludes.push(data)
}
},
//删除
DELETE_KEEPALIVEINCLUDES:(state, data) => {
state.keepAliveIncludes = state.keepAliveIncludes.filter(i=>i.always)
}
}
// 业务页面,使用keepAlive的组件
<template>
<keep-alive :include="keepAliveIncludes" >
<router-view ref="content"/>
</keep-alive>
</template>
<script>
export default {
computed: {
'keepAliveIncludes'() {
const arr = this.$store.state.keepAliveIncludes.map(i=>i.componentName)
return Array.from(new Set(arr))
},
}
</script>
这样就将keepAliveIncludes跟keepalive组件绑了,只需要对keepAliveIncludes这个值处理,组件内部会帮我们删除
通过全局路由钩子处理keepAliveIncludes
// 路由钩子
router.beforeEach((to, from, next) => {
let cachePath = store.state.keepAliveIncludes.map(i => i.keepAlive).flat(Infinity)
if (!cachePath.includes(to.name)) {
// console.log('去了不缓存的页面');
store.commit('DELETE_KEEPALIVEINCLUDES')
}
if (to.meta.keepAlive) {
// const componentsName = to.matched[to.matched.length-1].components.default.name
store.commit('SET_KEEPALIVEINCLUDES', {
path: `${to.name}`,
componentName: to.name, //要求路由name跟默认组件的name保持一致
always: to.meta.keepAlive.length === 0,
keepAlive: to.meta.keepAlive,
})
}
})
keepAlive缓存的方法先于router.beforeEach执行.
此功能还是有缺陷的
该方法需要默认路由组件name跟路由列表的name保持一致
因为keepAlive的include指令接收的值是组件name,而我们使用的是异步载入组件,所以在router.beforeEach时,组件还没有实例化,没办法拿到组件的name
当然如果是同步加载组件可以用下列代码拿到组件的name
to.matched[to.matched.length-1].components.default.name