一、使用场景
工作中遇到了一个页面需要根据不同情况决定是否需要缓存。
-
主要页面是:主页、列表页、详情页,需要进行缓存切换的是列表页。
-
主要操作流程为:主页 -> 列表 -> 详情 -> 列表 -> 主页,其中主页进入列表时需加载最新列表数据,从详情返回列表时则不对列表做修改
二、解决方案
-
主要技术:vue + vuex + keep-alive + keep-alive的 include 或者 exclude 属性,此处使用的是 include
-
具体方案: 使用 vuex 保存 include 属性值,在进入和离开列表页面之前对 include 做值的修改以切换是否缓存
-
代码实现:
(1)vuex
const store = new Vuex.Store({
state: {
includeArr: [], // keep-alive 需要缓存组件
},
getters: {
getIncludeArr: state => {
return state.includeArr;
},
},
mutations: {
/**
* 修改 keep-alive 的 include 属性值
* @param state
* @param payload
* - payload.includeArr: string[] ,要修改的组件数组
* - payload.isAdd: boolean, 是否为添加
*/
changeIncludeArr(state, payload){
let includeArr = payload.includeArr;
// 此处以字符串数组形式传入,可一次添加或删除多个;
// 若一次只操作一个也可不加此限制,则下方也做同步修改
if(Object.prototype.toString.call(includeArr).indexOf('Array')<0){
return;
}
if(includeArr && includeArr.length>0){
let includeTemp = new Set(state.includeArr);
if(payload.isAdd){ // 添加
includeArr.forEach(item => includeTemp.add(item));
}else{ //删除
includeArr.forEach(item => includeTemp.delete(item));
}
state.includeArr = [...includeTemp];
}
},
},
});
(2)Index.vue
<template>
<div>
<keep-alive :include="includeArr">
<router-view></router-view>
</keep-alive>
</div>
</template>
export default {
name: "Index",
data(){
return {}
},
computed:{
includeArr: function (){
return this.$store.getters.getIncludeArr
},
},
}
(3)List.vue
export default {
name: "List",
data() {
return {}
},
beforeRouteEnter(to, from, next){
// 进入当前页面之前先缓存
next(vm => {
vm.$store.commit('changeIncludeArr', {
isAdd: true,
includeArr: [vm.$options.name]
})
})
},
beforeRouteLeave(to, from, next){
// 离开前判断是否继续缓存此页面
// 除了前往详情页面,其他都不缓存
if(to.path.toLowerCase().indexOf('detail') <0){
this.$store.commit('changeIncludeArr', {
isAdd: false,
includeArr: [this.$options.name]
})
}
next();
},
}