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>
View Code
复制代码

 

_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()
            }
        }
    },
}
View Code
复制代码

 

_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
View Code
复制代码

 

posted @   Comedyy  阅读(2549)  评论(0编辑  收藏  举报
编辑推荐:
· 从 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的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示