聊一聊實(shí)現(xiàn)Vue路由組件緩存遇到的’坑‘

背景介紹

最近在做公司后臺(tái)管理系統(tǒng)項(xiàng)目時(shí)遇到一個(gè)比較怪異的bug——采用keep-alive+vue-router實(shí)現(xiàn)的路由緩存遇到緩存不生效的情況泣刹。

vue-router組件緩存未生效的bug

項(xiàng)目背景

此項(xiàng)目是基于iview-admin@2.0進(jìn)行開發(fā)的助析,全局狀態(tài)管理采用vuex分module實(shí)現(xiàn),路由采用vue-router進(jìn)行路由配置表的方式實(shí)現(xiàn)椅您。

項(xiàng)目屬于基于RBAC的后臺(tái)管理系統(tǒng)貌笨,需要多用戶多角色的權(quán)限控制,同時(shí)路由功能菜單以及展示的字段需按角色劃分襟沮,因此左側(cè)系統(tǒng)菜單根據(jù)接口進(jìn)行動(dòng)態(tài)設(shè)置锥惋。

項(xiàng)目中可以進(jìn)行菜單的圖標(biāo)、跳轉(zhuǎn)路徑开伏、是否隱藏等進(jìn)行配置膀跌,路徑對(duì)應(yīng)的前端路由則由前端的路由記錄進(jìn)行管理,即菜單管理功能設(shè)置的跳轉(zhuǎn)路徑是否可用由此路由記錄決定固灵。

解決過程

核實(shí)路由緩存用法問題

發(fā)現(xiàn)這個(gè)bug之后梳理了一遍路由組件緩存的實(shí)現(xiàn)方案捅伤,同時(shí)仔細(xì)核對(duì)了一遍vue-router的官方文檔

官方推薦的用法如下:

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

可以排除基本用法的問題,如是繼續(xù)翻閱vue的官方文檔巫玻,keep-alive的緩存匹配原理是根據(jù)組件的name作為key來(lái)進(jìn)行緩存丛忆,官方的提示

vue-router官網(wǎng)的提示

隨即檢查代碼中的路由記錄的name以及對(duì)應(yīng)component的name祠汇,發(fā)現(xiàn)都有定義好,因此排除基本用法的錯(cuò)誤導(dǎo)致熄诡。

iview-admin的不完善導(dǎo)致

進(jìn)行上述問題排查后定位到此問題出在keep-alive組件的include參數(shù)處可很,keep-alive的參數(shù)說(shuō)明如下:

  • include - 字符串或正則表達(dá)式。只有名稱匹配的組件會(huì)被緩存凰浮。
  • exclude - 字符串或正則表達(dá)式我抠。任何名稱匹配的組件都不會(huì)被緩存。
  • max - 數(shù)字袜茧。最多可以緩存多少組件實(shí)例菜拓。

iview-admin@2.0中通過路由的meata參數(shù)——notCache來(lái)控制路由對(duì)應(yīng)的組件是否進(jìn)行緩存,其源碼中有如下注釋說(shuō)明:

設(shè)為true后頁(yè)面在切換標(biāo)簽后不會(huì)緩存笛厦,如果需要緩存纳鼎,無(wú)需設(shè)置這個(gè)字段,而且需要設(shè)置頁(yè)面組件name屬性和路由配置的name一致

其文檔文檔上關(guān)于路由meta參數(shù)的說(shuō)明在這里裳凸。

其注釋說(shuō)明說(shuō)要讓組件實(shí)現(xiàn)緩存必須要保證頁(yè)面組件的name和路由配置的name一致贱鄙,而該項(xiàng)目中路由配置根據(jù)由后臺(tái)設(shè)置功能決定,故修改不能緩存的頁(yè)面的路由配置的namne即可解決問題登舞。

僅僅是解決了此bug總感覺還不夠贰逾,不如順便研究一個(gè)iview-admin的源碼是如何實(shí)現(xiàn)路由緩存的。

iview-admin實(shí)現(xiàn)路由組件緩存原理

iview-admin路由組件緩存原理
iview-admin路由組件緩存原理

iview-admin中將navTagList菠秒、menuList等數(shù)據(jù)保存在全局的vuex的app模塊中疙剑,navTagList是當(dāng)前的當(dāng)前打開過的標(biāo)簽頁(yè)數(shù)組根據(jù)路由變化動(dòng)態(tài)更新;menuList是當(dāng)前登錄用戶的菜單數(shù)組践叠,默認(rèn)根據(jù)路由記錄的meta參數(shù)的access字段進(jìn)行過濾

cacheList是app模塊的的getters之一言缤,用戶從tagNavList中計(jì)算出當(dāng)前打開的標(biāo)簽頁(yè)需要用keep-alive緩存的組件name數(shù)組,此處采用的是動(dòng)態(tài)修改keep-alive組件的exclude的值來(lái)動(dòng)態(tài)更新路由的緩存規(guī)則

iview-admin的一些局限

iview-admin中的用戶權(quán)限路由控制思路是:采用路由meata參數(shù)的access數(shù)組來(lái)標(biāo)簽當(dāng)前路由可訪問的用戶角色禁灼,根據(jù)路由記錄計(jì)算出對(duì)應(yīng)用戶的menuList進(jìn)行渲染管挟。

這個(gè)實(shí)現(xiàn)方案存在一些不足:

  • 路由采用配置表的方式由前端進(jìn)行配置,路由需要更新時(shí)需要前端更新代碼進(jìn)行打包部署的整套項(xiàng)目發(fā)布流程
  • 菜單完全由路由配置即用戶角色計(jì)算得出弄捕,后端不能夠靈活的重置頁(yè)面菜單顯示

基于以上這些考慮對(duì)iview-admin默認(rèn)的權(quán)限控制僻孝、路由配置進(jìn)行如下的優(yōu)化。

考慮優(yōu)化方案

路由分類劃分

項(xiàng)目中的路由組件包括Man.vue進(jìn)行布局控制守谓,404.vue 500.vue等處理前端路由異常的展示穿铆,login.vue error_log.vue等展示用戶注冊(cè)登錄日志記錄等頁(yè)面,這些頁(yè)面路由通常不會(huì)經(jīng)常更新不需要進(jìn)行動(dòng)態(tài)注冊(cè)斋荞,而像其他的復(fù)雜業(yè)務(wù)邏輯處理頁(yè)面需要接口進(jìn)行動(dòng)態(tài)配置荞雏。

故將路由進(jìn)行拆分,基礎(chǔ)路由——routers-common直接配置到router中,業(yè)務(wù)路由——routers進(jìn)行動(dòng)態(tài)注冊(cè)

路由分類

路由動(dòng)態(tài)注冊(cè)

vuex的store中的user模塊添加獲取用戶路由配置的action——getUserRoutes凤优,在用戶登錄成功后或者或者M(jìn)ain.vue的mounted生命周期中根據(jù)用戶token調(diào)用接口獲取用戶路由配置

調(diào)用router.addRoutes方法進(jìn)行路由的動(dòng)態(tài)注冊(cè)悦陋。

更進(jìn)一步

本文最終對(duì)遇到的vue路由緩存bug進(jìn)行了修復(fù),同時(shí)也對(duì)項(xiàng)目進(jìn)行了一定的優(yōu)化改造筑辨,后續(xù)對(duì)于vue-router源碼的進(jìn)一步研究也已經(jīng)完成俺驶,想知道本文遇到的’坑‘在源碼中是如何’埋下‘的,請(qǐng)閱讀我專欄的下一篇文章——帶你全面分析vue-router源碼(萬(wàn)字長(zhǎng)文)挖垛。

若此文對(duì)你有一點(diǎn)點(diǎn)幫助請(qǐng)點(diǎn)個(gè)贊鼓勵(lì)下作者痒钝,畢竟原創(chuàng)不易:)
首發(fā)自語(yǔ)雀:https://www.yuque.com/johniexu/frontend/dhgooo
作者博客地址:blog.lessing.online/
作者github:github.com/johniexu

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秉颗,一起剝皮案震驚了整個(gè)濱河市痢毒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚕甥,老刑警劉巖哪替,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菇怀,居然都是意外死亡凭舶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門爱沟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帅霜,“玉大人,你說(shuō)我怎么就攤上這事呼伸∩砑剑” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵括享,是天一觀的道長(zhǎng)搂根。 經(jīng)常有香客問我,道長(zhǎng)铃辖,這世上最難降的妖魔是什么剩愧? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮娇斩,結(jié)果婚禮上仁卷,老公的妹妹穿的比我還像新娘。我一直安慰自己犬第,他們只是感情好锦积,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瓶殃,像睡著了一般充包。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天基矮,我揣著相機(jī)與錄音淆储,去河邊找鬼。 笑死家浇,一個(gè)胖子當(dāng)著我的面吹牛本砰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钢悲,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼点额,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了莺琳?” 一聲冷哼從身側(cè)響起还棱,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惭等,沒想到半個(gè)月后珍手,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辞做,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年琳要,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秤茅。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稚补,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出框喳,到底是詐尸還是另有隱情课幕,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布帖努,位于F島的核電站撰豺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拼余。R本人自食惡果不足惜污桦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匙监。 院中可真熱鬧凡橱,春花似錦、人聲如沸亭姥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)达罗。三九已至坝撑,卻和暖如春静秆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背巡李。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工抚笔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侨拦。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓殊橙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親狱从。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膨蛮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354