vue自定義keepalive組件的問題解析
vue自定義keepalive組件
前一陣來了一個新的需求,要在vue項目中實現(xiàn)一個多開tab頁面的功能,本來心想,這不簡單嘛就是一個增加按鈕重定向嗎?(當然如果這么簡單我就不寫這個文章了)。很快寫完,提交測試。測試大哥很快就提交了一個問題:"你兩個tab頁訪問同一個鏈接,怎么還是個聯(lián)動的呢?"。我擦,這指定是緩存的問題。
為什么會出現(xiàn)這種情況呢
keep-alive組件是使用
include
exclude
這兩個屬性傳入組件名稱來確認哪些可以被緩存的
<keep-alive exclude="a,b,c" > <router-view></router-view> </keep-alive>
我們在看一下源碼,看看人家是怎么實現(xiàn)的(這兩張圖截的真難看)
主要邏輯(直說上述代碼)就是根據(jù)傳入的
include
,exclude
兩個屬性傳入數(shù)組,根據(jù)當前訪問的組件名稱判斷。我們相同鏈接都訪問同一個組件名稱(name)相同,第二次訪問的時候,鏈接指向的是同一個組件,因為使用組件的name作為緩存key,此時會被認為是讀取緩存操作,就會直接加載緩存并渲染,所以出現(xiàn)了兩個tab頁訪問同一個鏈接,出現(xiàn)聯(lián)動情況
如何解決這個問題呢
這個比較簡單之前是因為組件name當key導致的,那我們就不使用組件的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: { // 這里算是一個偽代碼 // 緩存的數(shù)組 [{ 'tab1/組件名稱':comp, 'tab2/組件名稱':comp },{ 'tab1/組件名稱':comp, 'tab2/組件名稱':comp }] cacheArray() { return this.$store.state.xxx.groupCache }, // 當前選中的分組 例:0/1/2... 這里用來讀取cache數(shù)組的index groupIndex() { return this.$store.state.xxx.groupIndex } }, created: function created() { // 當前tab的緩存 const cache = this.cacheArray[this.groupIndex] this.cache = cache || Object.create(null) // TODO 頁面初始化事件,后續(xù)可觸發(fā)初始化事件 }, destroyed: function destroyed(to, form) { // TODO 頁面離開事件,后續(xù)可觸發(fā)關閉事件 }, 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 { // 沒有進行緩存 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}` }, }
主題說完了,整點其他的
1. 在group-keep-alive組件中設置了abstract: true,設置當前組件為抽象組件,我的李姐:就是一個對下一級(包含子元素)事件監(jiān)聽等提前攔截,從而對下一級進行操作
2. router-view :key="key" 這key的作用是用來區(qū)分同一個組件是不是重復使用一個實例。
到此這篇關于vue自定義keepalive組件的文章就介紹到這了,更多相關vue keepalive組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue中監(jiān)聽input框獲取焦點及失去焦點的問題
這篇文章主要介紹了vue中監(jiān)聽input框獲取焦點,失去焦點的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07vue3?+?element-plus?的?upload?+?axios?+?django?實現(xiàn)文件上
這篇文章主要介紹了vue3?+?element-plus?的?upload?+?axios?+?django?文件上傳并保存,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01vue的異步數(shù)據(jù)更新機制與$nextTick用法解讀
這篇文章主要介紹了vue的異步數(shù)據(jù)更新機制與$nextTick用法解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03