vue keep-alive實現動態緩存以及緩存銷燬

vue keep-alive實現動態緩存以及緩存銷燬

需求來源及描述

後臺管理系統中,左側爲功能菜單欄,點擊菜單列表,右側顯示該菜單的功能頁面,本來是一個非常簡單的後臺管理系統佈局,現在增加了tabs菜單按鈕;
點擊左側菜單欄時,右側頁面頭部header顯示當前的頁面標題,形成一個tabs列表,點擊可切換頁面內容和關閉tabs;
需求要求,點擊左側時,右側顯示頁面內容,同時右側header增加該頁面的tabs,點擊tabs可以切換頁面,但頁面內容不刷新,點擊左側菜單時,右側內容刷新;

初步解決

第一想到的時利用vue的功能組件

<keep-alive>
    <router-view/>
</keep-alive>

此時只能實現緩存,但是不能根據需求實現動態緩存

解決方案

利用include來判斷需要緩存的路由組件,在根據點擊狀態更新include

<!-- html -->
<keep-alive :include="keepAliveList">
    <router-view :key="$route.fullPath"/>
</keep-alive>
利用計算屬性和vuex獲取緩存列表
<!-- vuex -->
state: {
        keepAliveList:'',//保存緩存的列表
    },
    mutations: {
        setKeepAliveLists(state,arrListString){
            state.keepAliveList = arrListString;
        },
        
    }
<!-- 視圖組件中 -->
computed:{
    keepAliveList(){
        // 獲取緩存的路由列表
        return this.$store.state.keepAliveList;
    }
}

生成緩存列表,列表的值爲各組件中name的值集合拼接的字符串

this.$store.commit('setKeepAliveLists',routerComponentNameList.join())

點擊左側菜單欄時,更新緩存列表

<!-- 點擊左側菜單的事件函數 -->
handleSelect(name) {
    if(this.routerNameMap.has(name)){//如果當前點擊的路由已經在緩存列表中,則先清除緩存列表,再添加;
        this.resetKeepAive(name,this.keepAliveList);//刪除緩存路由
        this.tabChangeRoute(name);//切換路由
    } else {
        this.routerNameMap.add(name)
        this.tabChangeRoute(name);
    }
},
// 更新要緩存的路由列表
resetKeepAive(name,cacheList) {
    const conf = this.keepAliveList;
    let arr = cacheList.split(',');
    if (name && typeof name === 'string') {
        let i = arr.indexOf(name);
        if (i > -1) {
            arr.splice(i, 1);
            this.$store.commit('setKeepAliveLists',arr.join());
            this.$nextTick(() => {//添加緩存路由
                this.$store.commit('setKeepAliveLists',conf);
            })
        }
    }
}

點擊右側tabs關閉標籤刪除緩存

removeTab(name){
    // 點擊tab上的關閉按鈕,清除當前路由的緩存
    this.routerNameMap.delete(name);
    this.resetKeepAive(name,this.keepAliveList);//刪除緩存路由
}

下面爲主要代碼,監聽當前路由是否被移除緩存,如果移除緩存則需要銷燬該組件,否則內容中的緩存組件會越來越來,影響使用性能;
創建一個mixin.js文件,然後引入到需要被動態緩存的路由組件中即可;

// 路由緩存管理
export default {
    computed: {
        keepAliveConf(){
            return this.$store.state.keepAliveList;
        }
    },
    watch:{
        keepAliveConf(e){
            // 監聽緩存列表的變化,如果緩存列表中沒有當前的路由或組件則在緩存中銷燬該實例
            let name = this.$options.name;
            if(!e.split(',').includes(name)) {
                this.$destroy()
            }
        }
    },
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章