Vue3 KeepAlive緩存組件實(shí)現(xiàn)方式
1. 內(nèi)置組件簡(jiǎn)介
在 Vue 中也提供了一些內(nèi)置組件:
- Transition(一個(gè)元素或組件進(jìn)入和離開 DOM 時(shí)應(yīng)用動(dòng)畫)
- TransitionGroup(對(duì) v-for 列表中的元素或組件的插入、移除和順序改變添加動(dòng)畫效果)
- KeepAlive(在多個(gè)組件間動(dòng)態(tài)切換時(shí)緩存被移除的組件實(shí)例)
- Teleport(將一個(gè)組件內(nèi)部的一部分模板“傳送”到該組件的 DOM 結(jié)構(gòu)外層的位置去)
- Suspense(在組件樹中協(xié)調(diào)對(duì)異步依賴的處理)
其中,KeepAlive 對(duì)于項(xiàng)目而言,最為常用,我們先進(jìn)行介紹,其他內(nèi)置組件,后續(xù)在添加具體的使用說明。
2. component 元素(動(dòng)態(tài)組件)
component 元素,一個(gè)用于渲染動(dòng)態(tài)組件或元素的“元組件”。要渲染的實(shí)際組件由 is prop 決定。
它是和 slot、template 等元素類似的一種特殊元素,這種元素是模板語法的一部分。但它們并非真正的組件,同時(shí)在模板編譯期間會(huì)被編譯掉。因此,它們通常在模板中用小寫字母書寫。
3. KeepAlive 基本使用方式
3.1 切換組件(未使用 KeepAlive,組件會(huì)銷毀再重新創(chuàng)建)
關(guān)鍵代碼:
<component :is="activeComponent" />




完整代碼如下。
父組件 App.vue:
<template>
<div>
<input type="radio" v-model="activeComponent" :value="A" />
<label for="A">A</label>
<input type="radio" v-model="activeComponent" :value="B" />
<label for="B">B</label>
</div>
<div>Current component:{{ activeComponent.__name }}</div>
<div>
<component :is="activeComponent" />
</div>
</template>
<script setup>
import { shallowRef, watch } from 'vue';
import A from '@/components/A.vue';
import B from '@/components/B.vue';
const activeComponent = shallowRef(A);
watch(activeComponent, (newVal) => {
console.log(newVal);
});
</script>
<style lang="scss" scoped>
div{
margin-bottom: 10px;
}
</style>
子組件 A.vue:
<template>
<div>
<span>Count: {{ count }}</span>
<button @click="count++">+</button>
</div>
</template>
<script setup name="A">
import { ref } from 'vue'
const count = ref(0)
</script>
<style lang="scss" scoped>
button{
margin-left: 10px;
}
</style>
子組件 B.vue:
<template>
<div>
<span>Message is: {{ message }}</span>
<input type="text" v-model="message" />
</div>
</template>
<script setup name="B">
import { ref } from 'vue'
const message = ref('')
</script>
<style lang="scss" scoped>
input{
margin-left: 10px;
}
</style>
3.2 切換組件(使用 KeepAlive,組件會(huì)進(jìn)行緩存)
修改 App.vue 的關(guān)鍵代碼,外部加上一層 KeepAlive:
<KeepAlive> <component :is="activeComponent" /> </KeepAlive>


使用 KeepAliec 后,組件間切換,組件會(huì)仍然保持之前的狀態(tài)。
此時(shí)的組件切換,屬于休眠/喚醒,而非銷毀/創(chuàng)建。
3. 使用細(xì)節(jié)
3.1 包含/排除(include/exclude)
在使用 KeepAlive 時(shí),會(huì)默認(rèn)緩存內(nèi)部的所有切換的組件。那如果我們只想緩存部分組件,可以通過 include 或 exclude prop 來定制該行為。
這兩個(gè) prop 的值都可以是一個(gè)以英文逗號(hào)分隔的字符串、一個(gè)正則表達(dá)式,或是包含這兩種類型的一個(gè)數(shù)組:
<!-- 以英文逗號(hào)分隔的字符串 --> <KeepAlive include="a,b"> <component :is="view" /> </KeepAlive> <!-- 正則表達(dá)式 (需使用 `v-bind`) --> <KeepAlive :include="/a|b/"> <component :is="view" /> </KeepAlive> <!-- 數(shù)組 (需使用 `v-bind`) --> <KeepAlive :include="['a', 'b']"> <component :is="view" /> </KeepAlive>
它會(huì)根據(jù)組件的 name 選項(xiàng)進(jìn)行匹配,所以組件如果想要條件性地被 KeepAlive 緩存,就必須顯式聲明一個(gè) name 選項(xiàng)。
在 3.2.34 或以上的版本中,使用 <script setup> 的單文件組件會(huì)自動(dòng)根據(jù)文件名生成對(duì)應(yīng)的 name 選項(xiàng),無需再手動(dòng)聲明。
3.2 最大緩存實(shí)例數(shù)(max)
通過傳入 max prop 來限制可被緩存的最大組件實(shí)例數(shù)。
<KeepAlive> 的行為在指定了 max 后類似一個(gè) LRU 緩存:如果緩存的實(shí)例數(shù)量即將超過指定的那個(gè)最大數(shù)量,則最久沒有被訪問的緩存實(shí)例將被銷毀,以便為新的實(shí)例騰出空間。
<KeepAlive :max="10"> <component :is="activeComponent" /> </KeepAlive>
3.3 緩存實(shí)例的生命周期(onActivated 和 onDeactivated)
當(dāng)一個(gè)組件實(shí)例從 DOM 上移除但因?yàn)楸?<KeepAlive> 緩存而仍作為組件樹的一部分時(shí),它將變?yōu)?strong>不活躍狀態(tài)而不是被卸載。當(dāng)一個(gè)組件實(shí)例作為緩存樹的一部分插入到 DOM 中時(shí),它將重新被激活。
一個(gè)持續(xù)存在的組件可以通過 onActivated() 和 onDeactivated() 注冊(cè)相應(yīng)的兩個(gè)狀態(tài)的生命周期鉤子:
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
// 調(diào)用時(shí)機(jī)為首次掛載
// 以及每次從緩存中被重新插入時(shí)
})
onDeactivated(() => {
// 在從 DOM 上移除、進(jìn)入緩存
// 以及組件卸載時(shí)調(diào)用
})
</script>
請(qǐng)注意:
- onActivated 在組件掛載時(shí)也會(huì)調(diào)用,并且 onDeactivated 在組件卸載時(shí)也會(huì)調(diào)用。
- 這兩個(gè)鉤子不僅適用于 緩存的根組件,也適用于緩存樹中的后代組件。
看個(gè)例子。A組件新增一個(gè)子組件A1,B組件新增一個(gè)子組件B1。
A1.vue:
<template>
<div>
這是A1組件內(nèi)容(A的子組件)
</div>
</template>
<script setup>
import { onActivated, onDeactivated } from 'vue';
onActivated(() => {
console.log('A1 onActivated')
})
onDeactivated(() => {
console.log('A1 onDeactivated')
})
</script>
<style lang="scss" scoped>
div{
margin-top: 10px;
}
</style>
A.vue:
<template>
<div class="A">
<span>Count: {{ count }}</span>
<button @click="count++">+</button>
<A1></A1>
</div>
</template>
<script setup name="A">
import { ref, onActivated, onDeactivated } from 'vue';
import A1 from './A1.vue'
const count = ref(0)
onActivated(() => {
console.log('A onActivated')
})
onDeactivated(() => {
console.log('A onDeactivated')
})
</script>
<style lang="scss" scoped>
.A{
border: 1px solid red;
padding: 10px;
}
button{
margin-left: 10px;
}
</style>
B1.vue:
<template>
<div>
這是B1組件內(nèi)容(B的子組件)
</div>
</template>
<script setup>
import { onActivated, onDeactivated } from 'vue';
onActivated(() => {
console.log('B1 onActivated')
})
onDeactivated(() => {
console.log('B1 onDeactivated')
})
</script>
<style lang="scss" scoped>
div{
margin-top: 10px;
}
</style>
B.vue:
<template>
<div class="B">
<span>Message is: {{ message }}</span>
<input type="text" v-model="message" />
<B1 />
</div>
</template>
<script setup name="B">
import { ref, onActivated, onDeactivated } from 'vue';
import B1 from './B1.vue'
const message = ref('')
onActivated(() => {
console.log('B onActivated')
})
onDeactivated(() => {
console.log('B onDeactivated')
})
</script>
<style lang="scss" scoped>
.B{
border: 1px solid red;
padding: 10px;
}
input{
margin-left: 10px;
}
</style>


總結(jié)下 onActivated(激.活), onDeactivated(休眠)生命周期鉤子的執(zhí)行順序:
- 由內(nèi)而外(先執(zhí)行子組件,再執(zhí)行父組件的);
- 由前到后(先執(zhí)行上個(gè)組件的休眠,再執(zhí)行下個(gè)組件的激活)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue實(shí)現(xiàn)input輸入模糊查詢的三種方式
本文主要介紹了vue實(shí)現(xiàn)input輸入模糊查詢的三種方式嗎,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
實(shí)例詳解vue.js淺度監(jiān)聽和深度監(jiān)聽及watch用法
這篇文章主要介紹了vue.js淺度監(jiān)聽和深度監(jiān)聽及watch用法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-08-08
vue element table 表格請(qǐng)求后臺(tái)排序的方法
今天小編就為大家分享一篇vue element table 表格請(qǐng)求后臺(tái)排序的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09
Vue3動(dòng)態(tài)組件component不生效問題解決方法
動(dòng)態(tài)組件component是Vue中非常實(shí)用的一個(gè)功能,它可以根據(jù)條件動(dòng)態(tài)切換不同的組件,在Vue3中使用方法和Vue2基本一致,在vue3使用component動(dòng)態(tài)組件展示組件時(shí),組件就是不展示顯示空白,所以本文記錄了Vue3動(dòng)態(tài)組件component不生效問題解決方法,需要的朋友可以參考下2024-08-08
在vue中使用el-tab-pane v-show/v-if無效的解決
這篇文章主要介紹了在vue中使用el-tab-pane v-show/v-if無效的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Vue+tracking.js 實(shí)現(xiàn)前端人臉檢測(cè)功能
這篇文章主要介紹了Vue+tracking.js 實(shí)現(xiàn)前端人臉檢測(cè)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
基于vue2.0的活動(dòng)倒計(jì)時(shí)組件countdown(附源碼下載)
這是一款基于vue2.0的活動(dòng)倒計(jì)時(shí)組件,可以使用服務(wù)端時(shí)間作為當(dāng)前時(shí)間,在倒計(jì)時(shí)開始和結(jié)束時(shí)可以自定義回調(diào)函數(shù)。這篇文章主要介紹了基于vue2.0的活動(dòng)倒計(jì)時(shí)組件countdown,需要的朋友可以參考下2018-10-10
Vue插槽檢測(cè)之$slots的妙用與最佳實(shí)踐指南
這篇文章主要介紹了Vue插槽檢測(cè)之$slots的妙用與最佳實(shí)踐指南的相關(guān)資料,$slots是一個(gè)具有只讀屬性的對(duì)象,用來訪問被插槽分發(fā)的內(nèi)容,文中將用法介紹的非常詳細(xì),需要的朋友可以參考下2026-03-03

