後臺管理系統中,左側爲功能菜單欄,點擊菜單列表,右側顯示該菜單的功能頁面,原本是一個很是簡單的後臺管理系統佈局,如今增長了tabs菜單按鈕;
點擊左側菜單欄時,右側頁面頭部header顯示當前的頁面標題,造成一個tabs列表,點擊可切換頁面內容和關閉tabs;
需求要求,點擊左側時,右側顯示頁面內容,同時右側header增長該頁面的tabs,點擊tabs能夠切換頁面,但頁面內容不刷新,點擊左側菜單時,右側內容刷新;html
第一想到的時利用vue的功能組件vue
<keep-alive> <router-view/> </keep-alive>
此時只能實現緩存,可是不能根據需求實現動態緩存vuex
利用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
文件,而後引入到須要被動態緩存的路由組件中便可;this
// 路由緩存管理 export default { computed: { keepAliveConf(){ return this.$store.state.keepAliveList; } }, watch:{ keepAliveConf(e){ // 監聽緩存列表的變化,若是緩存列表中沒有當前的路由或組件則在緩存中銷燬該實例 let name = this.$options.name; if(!e.split(',').includes(name)) { this.$destroy() } } }, }