vue中的keep-alive用法指南
什么是keep-alive?
keep-alive是Vue的一個(gè)內(nèi)置抽象組件,通常用于緩存動(dòng)態(tài)組件或路由組件。被keep-alive包裹的組件在切換時(shí)不會(huì)被銷毀,而是被緩存下來(lái),下一次切換回這個(gè)組件時(shí),會(huì)直接復(fù)用之前的實(shí)例,保持其狀態(tài)。
<template> <keep-alive> <component :is="view"></component> </keep-alive> </template> <script> export default { data() { return { view: 'homeComponent' }; } }; </script>
在這個(gè)例子中, homeComponent在被切換時(shí)不會(huì)被銷毀,而是被緩存,當(dāng)再次展示時(shí),狀態(tài)和數(shù)據(jù)都保持不變。
keep-alive重要的配置選項(xiàng)
1.include和exclude:用于控制哪些組件需要緩存,支持字符串、正則表達(dá)式或數(shù)組。
<keep-alive include="ComponentA, ComponentB" exclude="ComponentC"> <router-view></router-view> </keep-alive>
2.max:用于指定緩存的組件數(shù)量,當(dāng)超出這個(gè)數(shù)量時(shí),最久未使用的組件實(shí)例將被銷毀。
<keep-alive :max="6"> <router-view></router-view> </keep-alive>
生命周期鉤子
keep-alive還引入了兩個(gè)新的組件生命周期鉤子,用于處理緩存組件:
- activated:當(dāng)組件被激活時(shí)觸發(fā)(即從緩存中恢復(fù)時(shí))
- deactivated:當(dāng)組件被停用時(shí)觸發(fā)(即被緩存時(shí))
export default { activated() { console.log('組件被激活了'); }, deactivated() { console.log('組件被緩存了'); } };
適用場(chǎng)景
- 多頁(yè)簽(Tab)切換:在復(fù)雜的表單或多步操作場(chǎng)景中,用戶頻繁切換頁(yè)面,如果使用keep-alive,切換回來(lái)的頁(yè)面能保留之前輸入的數(shù)據(jù)或操作狀態(tài)。
- 路由緩存:在Vue項(xiàng)目中,常常會(huì)在路由切換時(shí)希望保持組件的狀態(tài),如商品詳情頁(yè)、搜索頁(yè)面等。
keep-alive的核心原理
- 緩存實(shí)例:當(dāng)組件被第一次加載時(shí),keep-alive會(huì)將組件的實(shí)例緩存起來(lái)。
- 組件復(fù)用:當(dāng)你切換到一個(gè)已經(jīng)被緩存的組件時(shí),keep-alive會(huì)從緩存中提取該組件的實(shí)例,而不是重新創(chuàng)建。
- 生命周期管理:為了處理組件的激活和停用,keep-alive引入了activated和deactivated鉤子,在組件進(jìn)入或離開緩存時(shí)觸發(fā)。
核心原理:
- 緩存實(shí)例:當(dāng)組件被第一次加載時(shí),keep-alive會(huì)將組件的實(shí)例緩存起來(lái)。
- 組件復(fù)用:當(dāng)你切換到一個(gè)已經(jīng)被緩存的組件時(shí),keep-alive會(huì)從緩存中提取該組件的實(shí)例,而不是重新創(chuàng)建。
- 生命周期管理:為了處理組件的激活和停用,keep-alive引入了activated和deactivated鉤子,在組件進(jìn)入或離開緩存時(shí)觸發(fā)。
keep-alive的源碼解析
以下時(shí)抽取的部分原理代碼:
export default { name: 'KeepAlive', abstract: true, // 這是一個(gè)抽象組件,表示它不會(huì)直接渲染到 DOM 上 props: { include: patternTypes, // 要緩存的組件 exclude: patternTypes, // 不緩存的組件 max: [String, Number] // 最大緩存數(shù) }, created () { this.cache = Object.create(null); // 緩存對(duì)象 this.keys = []; // 用來(lái)記錄緩存的順序 }, destroyed () { for (const key in this.cache) { pruneCacheEntry(this.cache, key, this.keys); } }, watch: { include (val) { pruneCache(this, name => matches(val, name)); }, exclude (val) { pruneCache(this, name => !matches(val, name)); } }, render () { const slot = this.$slots.default; const vnode = getFirstComponentChild(slot); // 獲取第一個(gè)子組件 if (vnode) { const componentOptions = vnode.componentOptions; const name = getComponentName(componentOptions); if (name && ( (this.include && !matches(this.include, name)) || (this.exclude && matches(this.exclude, name)) )) { return vnode; // 如果不匹配 include/exclude,直接返回,不緩存 } const key = vnode.key == null ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '') : vnode.key; if (this.cache[key]) { vnode.componentInstance = this.cache[key].componentInstance; // 從緩存中取出實(shí)例 remove(this.keys, key); // 移除舊的位置 this.keys.push(key); // 重新放到最后,更新 LRU 位置 } else { this.cache[key] = vnode; // 緩存新實(shí)例 this.keys.push(key); // 如果超過(guò)最大緩存數(shù),移除最早的實(shí)例 if (this.max && this.keys.length > parseInt(this.max)) { pruneCacheEntry(this.cache, this.keys[0], this.keys, this._vnode); } } vnode.data.keepAlive = true; // 標(biāo)記組件為 keep-alive } return vnode || (slot && slot[0]); // 返回 vnode } };
1.緩存機(jī)制
this.cache 是一個(gè)對(duì)象,用于存儲(chǔ)已經(jīng)緩存的組件實(shí)例
this.keys 是一個(gè)數(shù)組,用來(lái)記錄緩存組件的順序
2.組件的緩存和激活
在render函數(shù)中,Vue判斷當(dāng)前組件是否在inclue和exclude的范圍內(nèi)。如果匹配不到,則不進(jìn)行緩存。
通過(guò)key標(biāo)識(shí)組件,并將其與緩存實(shí)例關(guān)聯(lián)。如果組件已經(jīng)在緩存中,直接取出緩存的組件實(shí)例并復(fù)用。
3.LRU緩存策略
LRU緩存策略維持了一個(gè)有序的數(shù)據(jù)結(jié)構(gòu),記錄了緩存項(xiàng)的使用順序。當(dāng)緩存達(dá)到容量限制時(shí),它會(huì)移除最近最少使用的項(xiàng),以便為新的數(shù)據(jù)騰出空間,常見的實(shí)現(xiàn)方式包括使用雙向鏈表和哈希表的組合,來(lái)保持緩存項(xiàng)的順序和快速訪問(wèn)。
當(dāng)this.keys的長(zhǎng)度超過(guò)max時(shí),刪除最早的緩存組件(即this.keys[0])
4.生命周期的管理
activated和deactivated生命周期鉤子與keep-alive緊密相關(guān),它們?cè)诮M件被從緩存中激活和停用時(shí)觸發(fā)。activated和deactivated鉤子用于管理組件的激活和停用。
到此這篇關(guān)于vue中的keep-alive用法指南的文章就介紹到這了,更多相關(guān)vue keep-alive內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue中Keep-Alive緩存組件使用語(yǔ)法及原理深度解析
- Vue路由組件的緩存keep-alive和include屬性的具體使用
- Vue keep-alive組件的使用及如何清除緩存
- vue使用keep-alive無(wú)效以及include和exclude用法解讀
- Vue3嵌套路由中使用keep-alive緩存多層的實(shí)現(xiàn)
- vue使用keep-alive后從部分頁(yè)面進(jìn)入不緩存示例詳解
- vue使用keep-alive進(jìn)行組件緩存方法詳解(組件不緩存問(wèn)題解決)
- vue使用keep-alive如何實(shí)現(xiàn)多頁(yè)簽并支持強(qiáng)制刷新
相關(guān)文章
vue實(shí)現(xiàn)拖動(dòng)左側(cè)導(dǎo)航欄變大變小
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)拖動(dòng)左側(cè)導(dǎo)航欄變大變小,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03基于elementUI使用v-model實(shí)現(xiàn)經(jīng)緯度輸入的vue組件
這篇文章主要介紹了基于elementUI使用v-model實(shí)現(xiàn)經(jīng)緯度輸入的vue組件,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05Vue項(xiàng)目中引入ESLint校驗(yàn)代碼避免代碼錯(cuò)誤
這篇文章主要為大家介紹了Vue項(xiàng)目中引入ESLint插件校驗(yàn)代碼避免代碼錯(cuò)誤的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07基于axios請(qǐng)求封裝的vue應(yīng)用實(shí)例代碼
這篇文章主要給大家介紹了基于axios請(qǐng)求封裝的vue應(yīng)用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05vue安裝和使用scss及sass與scss的區(qū)別詳解
這篇文章主要介紹了vue安裝和使用教程,用了很久css預(yù)編譯器,但是一直不太清楚到底用的sass還是scss,直到有天被問(wèn)住了有點(diǎn)尷尬,感興趣的朋友一起看看吧2018-10-10require.js 加載 vue組件 r.js 合并壓縮的實(shí)例
這篇文章主要介紹了require.js 加載 vue組件 r.js 合并壓縮的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10element-ui upload組件上傳文件類型限制問(wèn)題小結(jié)
最近我遇到這樣的問(wèn)題,接受類型已經(jīng)加了accept 但是當(dāng)選擇彈出本地選擇文件時(shí)候切換到所有文件 之前的文件類型就本根過(guò)濾不掉了,下面小編給大家介紹element-ui upload組件上傳文件類型限制問(wèn)題小結(jié),感興趣的朋友一起看看吧2024-02-02詳解VUE里子組件如何獲取父組件動(dòng)態(tài)變化的值
這篇文章主要介紹了詳解VUE里子組件如何獲取父組件動(dòng)態(tài)變化的值,子組件通過(guò)props獲取父組件傳過(guò)來(lái)的數(shù)據(jù),子組件存在操作傳過(guò)來(lái)的數(shù)據(jù)并且傳遞給父組件,需要的朋友可以參考下2018-12-12