Vue keepalive缓存清理思路
涉及知识点:vuex,mixins,keepalive,route,computed,watch
1./store/index.js :
store:
keepAliveList:[],
mutations:
setKeepAliveLists(state,keepName){
state.keepAliveList.push(keepName);
},
removeKeepAliveItem(state,keepName){
state.keepAliveList.splice(state.keepAliveList.indexOf(keepName), 1)
},
2./components/TopWatch :(非左侧标签导航组件,点击路由切换,可关闭)
监听路由变化,当其meta.keepAlive为true时将该路由的name存入keepAliveList
this.$store.commit('setKeepAliveLists',storeCache);
点击关闭标签时,当其meta.keepAlive为true时将该路由的name存入keepAliveList
this.$store.commit('removeKeepAliveItem',storeCache);
3.引入mixins在需要动态销毁的组件里,监听store.state.keepAliveList
import mixin from '../../mixin'
export default {
mixins:[mixin],
}
4.当mixins所在组件的name不存在于store.state.keepAliveList时,执行this.$destroy()
export default {
computed: {
keepAliveConf(){
return this.$store.state.keepAliveList;
}
},
watch:{
keepAliveConf(e){
// 监听缓存列表的变化,如果缓存列表中没有当前的路由或组件则在缓存中销毁该实例
let name = this.$options.name;
if(!this.$store.state.keepAliveList.includes(name)) {
this.$destroy()
}
}
},
}
5.完整代码
_1./components/ToWatch.vue

<template> <div class="topwatch" > <el-tag :key="index" v-for="(tag,index) in dynamicTags" closable :effect="tag.active?'dark':'plain'" :disable-transitions="false" @click="tapClick(tag)" @close="tapClose(tag)"> {{tag.name}} </el-tag> </div> </template> <script> export default { name:'Topwatch', props:{ routerVal: Object, }, computed: { isShow() { return this.routerVal } }, watch: { isShow:{ //深度监听,可监听到对象、数组的变化 handler (routerVal) { // do something, 可使用this this.handleInputConfirm(routerVal); }, deep:true } }, data() { return { dynamicTags: [], }; }, methods: { tapClick(tag){ this.$router.push({path:tag.path}) }, tapClose(tag) { //处理keepalive:当关闭标签为缓存组件时,清除其在store里对应keepAliveList if(tag.meta.keepAlive){ this.$store.commit('removeKeepAliveItem',tag.path.substring(1)); } //当关闭标签非第一个标签时,跳到上一个标签所在路由位置,防止destroy后页面视图还存在 if(this.dynamicTags.indexOf(tag)-1>=0){ let goRouter = this.dynamicTags[this.dynamicTags.indexOf(tag)-1].path; console.log(goRouter); this.$router.push({path:goRouter}); }else{ this.$router.push({path:"/indexdata"}); } //清除标签视图 this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1); }, handleInputConfirm(e) { if(this.dynamicTags!=""){ let routerArr = this.dynamicTags; for(var j in routerArr){ this.$set(this.dynamicTags[j],"active",false); } for(var i in routerArr){ if(routerArr[i].name==e.name){ this.$set(this.dynamicTags[i],"active",true); return; } } } let inputValue = e; if (inputValue) { this.dynamicTags.push(inputValue); //处理keepalive:当生成标签为缓存组件时,添加其在store里对应keepAliveList if(inputValue.meta.keepAlive){ let storeCache = inputValue.path.substring(1); this.$store.commit('setKeepAliveLists',storeCache); } } } } } </script> <style lang="less" scoped> .topwatch{ padding:5px 0; } .el-tag { margin: 5px 0px 5px 8px; cursor: pointer; } .button-new-tag { margin-left: 10px; height: 32px; line-height: 30px; padding-top: 0; padding-bottom: 0; } .input-new-tag { width: 90px; margin-left: 10px; vertical-align: bottom; } </style>
_2.mixin.js

export default { computed: { keepAliveConf(){ return this.$store.state.keepAliveList; } }, watch:{ keepAliveConf(e){ // 监听缓存列表的变化,如果缓存列表中没有当前的路由或组件则在缓存中销毁该实例 let name = this.$options.name; if(!this.$store.state.keepAliveList.includes(name)) { this.$destroy() } } }, }
_3.store/index.js

import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) //创建VueX对象 const store = new Vuex.Store({ state:{ bgColor:'#545c64', textColor:'#fff', activeColor:'#ffd04b', contentBGC:'#fff', contentTextColor:"#222", keepAliveList:[], //保存缓存的列表 }, mutations:{ setKeepAliveLists(state,keepName){ state.keepAliveList.push(keepName); }, removeKeepAliveItem(state,keepName){ state.keepAliveList.splice(state.keepAliveList.indexOf(keepName), 1) }, changeColor(state,val){ if(val==1){ state.bgColor = '#545c64'; state.textColor = '#fff'; state.activeColor = '#ffd04b'; state.contentBGC = '#fff'; state.contentTextColor = "#222"; } if(val==2){ state.bgColor = '#fff'; state.textColor = '#606266'; state.activeColor = '#409EFF'; state.contentBGC = '#fff'; state.contentTextColor = "#222"; } if(val==3){ state.bgColor = '#333333'; state.textColor = '#a29f9f'; state.activeColor = '#e25132'; state.contentBGC = '#f5f5f5'; state.contentTextColor = "#222"; } localStorage.setItem("systemColor",val) } } }) export default store
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~