vue自定義keepalive組件的問題解析
vue自定義keepalive組件
前一陣來了一個(gè)新的需求,要在vue項(xiàng)目中實(shí)現(xiàn)一個(gè)多開tab頁面的功能,本來心想,這不簡單嘛就是一個(gè)增加按鈕重定向嗎?(當(dāng)然如果這么簡單我就不寫這個(gè)文章了)。很快寫完,提交測試。測試大哥很快就提交了一個(gè)問題:"你兩個(gè)tab頁訪問同一個(gè)鏈接,怎么還是個(gè)聯(lián)動(dòng)的呢?"。我擦,這指定是緩存的問題。
為什么會(huì)出現(xiàn)這種情況呢
keep-alive組件是使用
include
exclude
這兩個(gè)屬性傳入組件名稱來確認(rèn)哪些可以被緩存的
<keep-alive exclude="a,b,c" > <router-view></router-view> </keep-alive>
我們在看一下源碼,看看人家是怎么實(shí)現(xiàn)的(這兩張圖截的真難看)
主要邏輯(直說上述代碼)就是根據(jù)傳入的
include
,exclude
兩個(gè)屬性傳入數(shù)組,根據(jù)當(dāng)前訪問的組件名稱判斷。我們相同鏈接都訪問同一個(gè)組件名稱(name)相同,第二次訪問的時(shí)候,鏈接指向的是同一個(gè)組件,因?yàn)槭褂媒M件的name作為緩存key,此時(shí)會(huì)被認(rèn)為是讀取緩存操作,就會(huì)直接加載緩存并渲染,所以出現(xiàn)了兩個(gè)tab頁訪問同一個(gè)鏈接,出現(xiàn)聯(lián)動(dòng)情況
如何解決這個(gè)問題呢
這個(gè)比較簡單之前是因?yàn)榻M件name當(dāng)key導(dǎo)致的,那我們就不使用組件的name作為key了,改為name+tab的index作為key。
問題知道了怎么解決呢
思路有了擼代碼
group-keep-alive.js
function remove(arr, item) { if (arr.length) { var index = arr.indexOf(item) if (index > -1) { return arr.splice(index, 1) } } } function getFirstComponentChild(children) { if (Array.isArray(children)) { for (var i = 0; i < children.length; i++) { var c = children[i] if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) { return c } } } } function isDef(v) { return v !== undefined && v !== null } function isAsyncPlaceholder(node) { return node.isComment && node.asyncFactory } var patternTypes = [String, RegExp, Array] export default { name: 'keep-alive', abstract: true, computed: { // 這里算是一個(gè)偽代碼 // 緩存的數(shù)組 [{ 'tab1/組件名稱':comp, 'tab2/組件名稱':comp },{ 'tab1/組件名稱':comp, 'tab2/組件名稱':comp }] cacheArray() { return this.$store.state.xxx.groupCache }, // 當(dāng)前選中的分組 例:0/1/2... 這里用來讀取cache數(shù)組的index groupIndex() { return this.$store.state.xxx.groupIndex } }, created: function created() { // 當(dāng)前tab的緩存 const cache = this.cacheArray[this.groupIndex] this.cache = cache || Object.create(null) // TODO 頁面初始化事件,后續(xù)可觸發(fā)初始化事件 }, destroyed: function destroyed(to, form) { // TODO 頁面離開事件,后續(xù)可觸發(fā)關(guān)閉事件 }, render: function render() { var slot = this.$slots.default var vnode = getFirstComponentChild(slot) var componentOptions = vnode && vnode.componentOptions // check pattern var ref$1 = this var cache = ref$1.cache const key = `${this.groupIndex}/${componentOptions.Ctor.options.name}` // 存在key直接讀取 if (cache[key]) { vnode.componentInstance = cache[key].componentInstance } else { // 沒有進(jìn)行緩存 cache[key] = vnode } // 寫入緩存 this.$store.dispatch('setGroupCache', { cache: this.cache }) return vnode || (slot && slot[0]) } }
如何使用
意思一下就行了
<group-keep-alive> <router-view :key="key" /> /group-keep-alive> // key一定要區(qū)分 computed: { key() { return `${選中index}/${fullpath}` }, }
主題說完了,整點(diǎn)其他的
1. 在group-keep-alive組件中設(shè)置了abstract: true,設(shè)置當(dāng)前組件為抽象組件,我的李姐:就是一個(gè)對下一級(包含子元素)事件監(jiān)聽等提前攔截,從而對下一級進(jìn)行操作
2. router-view :key="key" 這key的作用是用來區(qū)分同一個(gè)組件是不是重復(fù)使用一個(gè)實(shí)例。
到此這篇關(guān)于vue自定義keepalive組件的文章就介紹到這了,更多相關(guān)vue keepalive組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3環(huán)境安裝以及項(xiàng)目搭建全過程
Vue工程化項(xiàng)目環(huán)境配置還是比較麻煩的,下面這篇文章主要給大家介紹了關(guān)于Vue3環(huán)境安裝以及項(xiàng)目搭建的相關(guān)資料,文中通過圖文以及代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12vue+j簡單的實(shí)現(xiàn)輪播效果,滾動(dòng)公告,銜接
這篇文章主要介紹了vue+j簡單的實(shí)現(xiàn)輪播效果,滾動(dòng)公告,銜接,文章圍繞主題的相關(guān)資料展開詳細(xì)的內(nèi)容具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06vue中監(jiān)聽input框獲取焦點(diǎn)及失去焦點(diǎn)的問題
這篇文章主要介紹了vue中監(jiān)聽input框獲取焦點(diǎn),失去焦點(diǎn)的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07vue3?+?element-plus?的?upload?+?axios?+?django?實(shí)現(xiàn)文件上
這篇文章主要介紹了vue3?+?element-plus?的?upload?+?axios?+?django?文件上傳并保存,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01vue的異步數(shù)據(jù)更新機(jī)制與$nextTick用法解讀
這篇文章主要介紹了vue的異步數(shù)據(jù)更新機(jī)制與$nextTick用法解讀,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03