vue-router keep-alive缓存策略
- App.vue中配置keep-alive,通过vuex中的缓存路由数组动态判断是否需要缓存当前组件
<template>
<div id="app" class="g-root">
<keep-alive :include="$store.state.common.cachedRouteNames">
<router-view />
</keep-alive>
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
在一些情况下,某些路由并不需要一直被缓存,只是从某些页面跳转回来时需要缓存参数,如管理页面的二级、三级路由返回到一级路由,而同级路由并不一定需要有缓存关系。
2. routes.js配置路由信息
{
path: '/page1',
name: 'page1',
component: page1,
meta: {
pageName: '第一页',
keepAlive: true,
cacheWhenFromRoutes: ['page2', 'page3']
}
},
通过meta标签中配置的keep-alive来判断是否需要缓存组件,通过cacheWhenFromRoutes判断从哪些页面跳转回来需要读取缓存
- 配置routerWatch
import store from '../store'
import router from './router'
// 需要缓存的路由名称数组
const cacheRouteList = store.state.common.cacheRouteList
// 添加路由信息
consr addRoute = (route)=>{
const routeName = route.components.default.name // 配置在单页面vue文件的name
if(route && !cacheRouteList(routeName)){
store.commit('updateCacheRouteList',{
action:'add',
route:routeName
})
}
}
// 删除路由信息
consr deleteRoute = (route)=>{
const routeName = route.components.default.name // 配置在单页面vue文件的name
if(route && cacheRouteList(routeName)){
store.commit('updateCacheRouteList',{
action:'delete',
route:routeName
})
}
}
/**
*@functionName: isNeedCacheTarget
*@params1: to 要跳转的路由
*@params2: from 从哪个路由来
*@description: 判断是否需要缓存要跳转的页面
*@author:
*@date:
*@version:
*/
const isNeedCacheTarget= (to, from) => {
let cacheFlag = false
const targetRoute = to.matched.find(item => item.path === to.path)
if (!targetRoute) return false
// 取路由配置信息meta中的keep-alive属性
const keepAlive = targetRoute.meta ? targetRoute.meta.keepAlive : false
const cacheWhenFromRoutes = targetRoute.meta && targetRoute.meta.cacheWhenFromRoutes ? targetRoute.meta.cacheWhenFromRoutes : []
// 缓存情况有以下
// 1. 没设置cacheWhenFromRoutes,一直缓存
// 2. 设置了cacheWhenFromRoutes,但是页面是首次打开的,所以from.name为空
// 3. 设置了cacheWhenFromRoutes,页面是从别的页面跳转而来,from.name不为空,并且命中了cacheWhenFromRoutes
if (keepAlive && (!cacheWhenFromRoutes.length || !from.name || cacheWhenFromRoutes.includes(from.name))) {
cacheFlag = true
}
return cacheFlag
}
//全局混入路由导航守卫
Vue.mixin({
// 从页面A-->B,如果B页面没有设置缓存,或者A页面不在B的cacheWhenFromRoutes配置当中
// 是不需要读取B页面的缓存的,对应的,删除B页面的缓存配置
beforeRouteEnter(to, from, next) {
if (!isNeedCacheTarget(to, from)) {
const toRoute = to.matched.find(route => route.path == to.path)
deleteRoutes(toRoute)
}
next()
},
// 从页面B-->A,如果B页面设置了缓存,并且A页面是在B页面的缓存配置中的,那么在B页面离开的时候
// 缓存B页面的信息
beforeRouteLeave(to, from, next) {
if (isNeedCacheTarget(from, to)) {
const fromRoute = from.matched.find(route => route.path == from.path)
addRoutes(fromRoute)
}
next()
}
})