Vue3之組件狀態(tài)保持KeepAlive的簡(jiǎn)單使用
作用說(shuō)明
一個(gè)應(yīng)用場(chǎng)景
當(dāng)我們?cè)谶M(jìn)行路由跳轉(zhuǎn)的時(shí)候,會(huì)用到 <router-view> 來(lái)作為 組件渲染的出口, 此時(shí),組件的狀態(tài)是不會(huì)被保持的。
比如 : 當(dāng)前在【組件A】中有一個(gè)響應(yīng)式狀態(tài) num 的值通過(guò) 自加的方式 從初始值0 變成了 100;
然后跳轉(zhuǎn)到 【組件B】,
再次跳轉(zhuǎn) 回到 【組件A】 的時(shí)候,num 的值會(huì) 恢復(fù)為初始值 0。
如何實(shí)現(xiàn) 回到 【組件A】的時(shí)候,仍然保持 num 的數(shù)據(jù)狀態(tài)為 100 呢?
這就是本文要介紹的 KeepAlive 組件的作用。
它就是用來(lái)做組件狀態(tài)保持的,或者叫做 緩存組件實(shí)例。
KeepAlive的簡(jiǎn)單介紹
1、 直接使用 <keep-alive> 標(biāo)簽,將目標(biāo)組件包起來(lái),就實(shí)現(xiàn)了組件的緩存;
2、配合路由的時(shí)候,需要使用到下面的格式 : 這個(gè)格式是固定的:
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
3、組件在緩存的時(shí)候,有兩個(gè)聲明周期鉤子可以配合使用:
onActivated: 組件在被激活時(shí)觸發(fā)onDeactivated: 組件在跳轉(zhuǎn)走被緩存時(shí)觸發(fā)
4、KeepAlive 有兩個(gè)屬性 :
include: 指定要緩存的組件exculde: 指定不要緩存的組件
以上兩個(gè)屬性 的值是 組件的名稱, 可以是 數(shù)組的形式指定多個(gè)組件。
例如 : 有 兩個(gè)組件,name 分別是 a 和 b
- 例1 :
<keep-alive include="a"> - 例2 :
<keep-alive :include="['a','b']">
注意,當(dāng)是數(shù)組的時(shí)候,需要使用 :的形式。
代碼案例
本案例 有兩個(gè)普通的組件,分別包含了響應(yīng)式狀態(tài),
App.vue 中通過(guò) 按鈕 進(jìn)行兩個(gè)組件的切換;
- 觀察 1:兩個(gè)組件的響應(yīng)式狀態(tài)是否保存了 ;
- 觀察2 :兩個(gè)組件的聲明周期鉤子。
本案例的項(xiàng)目結(jié)構(gòu)如下:
projectName
| -- src
| -- App.vue # 根組件
| -- componentA.vue # 組件A
| -- componentB.vue # 組件B
| -- main.ts # 程序入口文件
| -- router.ts # 路由配置文件
| -- index.html # 項(xiàng)目的入口文件案例代碼
組件A componentA.vue
<template>
<div class="diva">
這是組件A
<br>
countNum : {{ countNum }}
<br>
<button @click="countNum++">+</button>
<button @click="countNum--">-</button>
</div>
</template>
<script setup lang="ts">
// 指定組件名稱
defineOptions({
name:'ca'
})
import { ref,onMounted,onUnmounted,onActivated,onDeactivated} from 'vue'
const countNum = ref(0)
// 組件掛載成功后
onMounted(()=>{
console.log('組件A onMounted')
})
// 組件卸載成功后
onUnmounted(() => {
console.log('組件A onUnmounted')
}),
// 組件激活
onActivated(()=>{
console.log('組件A onActivated')
})
// 組件失活
onDeactivated(()=>{
console.log('組件A onDeactivated')
})
</script>
<style scoped>
.diva{
width: 300px;
height: 200px;
background: red;
}
</style>
組件B componentB.vue
<template>
<div class="divb">
這是組件B
<br>
message : {{ message }}
<br>
輸入框 :<input type="text" v-model="message" />
</div>
</template>
<script setup lang="ts">
// 指定組件名稱
defineOptions({
name:'cb'
})
import { ref,onMounted,onUnmounted,onActivated,onDeactivated} from 'vue'
const message = ref('')
// 組件掛載成功后
onMounted(()=>{
console.log('組件B onMounted')
})
// 組件卸載成功后
onUnmounted(() => {
console.log('組件B onUnmounted')
}),
// 組件激活
onActivated(()=>{
console.log('組件B onActivated')
})
// 組件失活
onDeactivated(()=>{
console.log('組件B onDeactivated')
})
</script>
<style scoped>
.divb{
width: 250px;
height: 150px;
background: green;
}
</style>
路由配置 router.ts
// 導(dǎo)入 定義路由的兩個(gè)方法
import {createRouter,createWebHistory} from 'vue-router'
// 懶加載寫法 : 先聲明,下面直接使用
const componentA = () => import('./componentA.vue')
const componentB = () => import('./componentB.vue')
// 聲明路由跳轉(zhuǎn)的路徑與組件的對(duì)應(yīng)關(guān)系
const routsList = [
// 直接使用上面聲明的組件
{path:'/a',name:'aroute',component:componentA},
{path:'/b',name:'broute',component:componentB}
]
// 創(chuàng)建路由的實(shí)例對(duì)象
const routerConfigObj = createRouter({
history:createWebHistory('abc'), // 帶一個(gè)參數(shù),表示是路由的一個(gè)前綴
routes:routsList // 指定路由的配置列表
})
// 導(dǎo)出路由的對(duì)象
export default routerConfigObj;
根組件 App.vue
<template>
<div class="basediv">
APP.vue 中的 msg : {{ msg }}
<br>
<button @click="$router.push('/a')">跳轉(zhuǎn)到A</button>
<button @click="$router.push('/b')">跳轉(zhuǎn)到B</button>
<br>
<!-- 核心 : keep-alive 的使用 -->
<router-view v-slot="{ Component }">
<!-- :exclude="['ca','cb']" -->
<keep-alive :include="['ca','cb']">
<component :is="Component" />
</keep-alive>
</router-view>
</div>
</template>
<script setup lang="ts">
// 引入 provide 方法
import { ref } from 'vue'
// 聲明父組件的一個(gè)變量
const msg = ref('這是App根組件的msg變量')
</script>
<style scoped>
.basediv{
width: 600px;
height: 400px;
border: 1px solid red;
}
</style>
運(yùn)行結(jié)果
》1、初始狀態(tài) : 組件A中的數(shù)字執(zhí)行幾次自增

》2、點(diǎn)擊 跳轉(zhuǎn)到 組件B
| 點(diǎn)擊前 | 跳轉(zhuǎn)后 |
|---|---|
![]() | ![]() |
》3、組件B中的輸入框輸入內(nèi)容

》4、點(diǎn)擊跳轉(zhuǎn)回 組件A

》5、再次跳轉(zhuǎn)回 組件B

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
element-ui表格合并span-method的實(shí)現(xiàn)方法
這篇文章主要介紹了element-ui表格合并span-method的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Vue計(jì)算屬性computed與方法methods的區(qū)別及說(shuō)明
這篇文章主要介紹了Vue計(jì)算屬性computed與方法methods的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue+elementUI?el-input輸入框手機(jī)號(hào)校驗(yàn)功能
這篇文章主要介紹了Vue+elementUI?el-input輸入框手機(jī)號(hào)校驗(yàn)功能,限制input框內(nèi)只能輸入數(shù)字,且為11位,通過(guò)實(shí)例代碼介紹了對(duì)輸入手機(jī)號(hào)做校驗(yàn)的方法,感興趣的朋友跟隨小編一起看看吧2023-10-10
vue3+ts項(xiàng)目搭建的實(shí)現(xiàn)示例
這篇文章主要介紹了vue3+ts項(xiàng)目搭建的實(shí)現(xiàn)示例,本文目的在于記錄自己項(xiàng)目框架搭建的過(guò)程,通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03
Vue.js計(jì)算屬性的變化監(jiān)聽的示例詳解
在Vue.js中,計(jì)算屬性(computed properties)是組件的重要組成部分,它們根據(jù)組件的數(shù)據(jù)自動(dòng)計(jì)算新的值,并在數(shù)據(jù)變化時(shí)自動(dòng)更新,本文將深入探討如何在Vue.js中監(jiān)聽計(jì)算屬性的變化,幫助你更好地理解Vue.js的響應(yīng)式系統(tǒng),需要的朋友可以參考下2025-03-03
vue3之Suspense加載異步數(shù)據(jù)的使用
本文主要介紹了vue3之Suspense加載異步數(shù)據(jù)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
vue+element模態(tài)框中新增模態(tài)框和刪除功能
這篇文章主要介紹了vue+element模態(tài)框中新增模態(tài)框和刪除功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
vue使用socket與服務(wù)端進(jìn)行通信的代碼詳解
這篇文章主要給大家介紹了vue如何使用socket與服務(wù)端進(jìn)行通信的相關(guān)資料,在Vue中我們可以將Websocket類封裝成一個(gè)Vue插件,以便全局使用,需要的朋友可以參考下2023-09-09



