使用vue-element-admin腳手架做系統(tǒng)時(shí),一般系統(tǒng)的側(cè)邊欄都是有父級(jí)议慰,子級(jí)别凹,子子級(jí),發(fā)現(xiàn)使用keep-alive到涂,當(dāng)三級(jí)以上的路由時(shí),無法緩存頁面浇雹?屿讽?
那首先要了解下keep-alive的作用是啥?
- 是用來對(duì)頁面組件進(jìn)行緩存不緩存的處理烂完,擁有緩存頁面組件诵棵,再次進(jìn)入時(shí)履澳,使用原來已經(jīng)加載好的內(nèi)容,可以大大的節(jié)省請(qǐng)求和渲染時(shí)間柄冲,是個(gè)好東西忠蝗!
相關(guān)的文章介紹很多,就不贅述了戒祠。闽撤。。(感興趣的多查查其他文章)
那它具體的屬性有2種:
- include ,包含頁面組件name的這些組件頁面,會(huì)被緩存起來
- exclude 除了這些name以外的頁面組件闸餐,會(huì)被緩存起來
- 還有第3種矾芙,如下這樣寫(即沒有include或者exclude屬性,表示所有的路由組件都會(huì)被緩存起來7髡 !)
如下所示:
<keep-alive>
<router-view :key="key" />
</keep-alive>
computed: {
key() {
return this.$route.path
}
}
注意這里有個(gè)坑點(diǎn):
- 發(fā)現(xiàn)keep-alive中的include屬性或者exclude屬性都不管用斗锭!后來查閱了一番岖是,發(fā)現(xiàn)這個(gè)include 或者exclude的name 是頁面組件里面具體的name实苞, 就像這樣:(凡是是路由組件,在對(duì)應(yīng)的這個(gè)組件頁面顯示的添著補(bǔ)上對(duì)應(yīng)的name屬性按辖巍猾浦!別偷懶T狙病)
(1)官方vue組件的name的命名方式,參考鏈接: https://cn.vuejs.org/v2/guide/components-registration.html
這里外莲,由于默認(rèn)的eslint配置文件.eslintrc.js中兔朦,如下:
即頁面組件的name , 如果不是大寫字母開頭沽甥,就會(huì)飄紅報(bào)錯(cuò)。(我有點(diǎn)強(qiáng)迫癥)所以頁面所有的路由組件具體頁面的name亥曹,我都以大寫字母開始命名
(2)這個(gè)具體vue組件頁面的name要跟你router文件中配置的name一樣
因?yàn)樵诿看未蜷_標(biāo)簽頁和關(guān)閉標(biāo)簽頁處理時(shí)媳瞪,是根據(jù)name來匹配照宝,進(jìn)行添加刪除。如果組件內(nèi)部頁面配置的name是Order,而路由文件配置的name是order,那include和exclude也不會(huì)有用兢仰!
準(zhǔn)備工作做好了后,就可以使用keep-alive 啦
include 屬性進(jìn)行緩存頁面組件的操作了轻专,實(shí)現(xiàn)參考了github這篇: https://github.com/PanJiaChen/vue-element-admin/commit/9ad96525af3a26c2f4e8d4e9016f801c44df1f80
上面這個(gè)鏈接的代碼秸弛,實(shí)現(xiàn)了三級(jí)路由以上的緩存處理:(但還會(huì)有個(gè)問題递览,刷新或者關(guān)閉當(dāng)前標(biāo)簽頁叼屠,再次打開時(shí),清除不了當(dāng)前組件的緩存(比如搜索條件寫了個(gè)東西绞铃,進(jìn)行搜索镜雨,關(guān)閉或者刷新后,應(yīng)該清空重新請(qǐng)求儿捧,但還是保留荚坞。。我們后面會(huì)解決的菲盾,先接著往下看~))
上述鏈接的解決的思路如下:
- 代碼如下:(三級(jí)路由根頁面代碼)
Parent
<script>
export default {
name: 'Menu1',
data() {
return {
...
}
},
created() {
const route = this.$route.matched.find(item => item.name === 'Menu1')
this.$store.dispatch('tagsView/addCachedView', route)
}
}
</script>
注: 上述組件的name值和find比較的name 值要均保持一致颓影,這里,如果當(dāng)前組件的name改變了后懒鉴,代碼改動(dòng)的地方有2處诡挂,有沒有更取巧的方式呢临谱,如下代碼璃俗,就可以直接獲取當(dāng)前組件的name, 而不用相同的name寫兩遍
this.$options.name
所以上述代碼,我們有可以改寫成這樣:
Parent
<script>
export default {
name: 'Menu1',
data() {
return {
...
}
},
created() {
const route = this.$route.matched.find(item => item.name === this.$options.name)
this.$store.dispatch('tagsView/addCachedView', route)
}
}
</script>
那又回到剛才說的問題了悉默,刷新或者關(guān)閉再打開當(dāng)前3級(jí)路由的標(biāo)簽頁時(shí)城豁,緩存未清空?
問題總是有解決辦法的抄课,參考鏈接是這個(gè)issue: https://github.com/PanJiaChen/vue-element-admin/pull/3116
tagsView.js
addCachedView({ commit }, view) {
if (view.matched && view.matched.length >= 3) { // 若為三級(jí)及其以上路由點(diǎn)擊打開標(biāo)簽頁時(shí)唱星,將三級(jí)路由或以上的根目錄路由塞入緩存路由name list中
commit('ADD_CACHED_VIEW', view.matched[1])
}
commit('ADD_CACHED_VIEW', view) // 反之,正常的進(jìn)行標(biāo)簽頁的添加進(jìn)緩存路由name list中
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
if (view.matched && view.matched.length >= 3) { // 若為三級(jí)及其以上路由關(guān)閉當(dāng)前標(biāo)簽頁時(shí)跟磨,將3級(jí)路由以上的根目錄name 從list中刪除
commit('DEL_CACHED_VIEW', view.matched[1])
}
commit('DEL_CACHED_VIEW', view) // 反之魏颓,正常的進(jìn)行標(biāo)簽頁的name 從list中刪除
resolve([...state.cachedViews])
})
},
以上解決問題啦~~<( ̄▽ ̄)/
還要注意的是:
AppMain.vue里這樣寫:(注意include方法,取的是cachedViews)
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view :key="key" />
</keep-alive>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
}
}
</script>
<style scope>
...
</style>