vue緩存之keep-alive的理解和應(yīng)用詳解
官方解釋:
<keep-alive> 包裹動態(tài)組件時,會緩存不活動的組件實例,而不是銷毀它們。和 <transition> 相似,<keep-alive> 是一個抽象組件:它自身不會渲染一個 DOM 元素,也不會出現(xiàn)在組件的父組件鏈中。
當(dāng)組件在 <keep-alive> 內(nèi)被切換,它的 activated 和 deactivated 這兩個生命周期鉤子函數(shù)將會被對應(yīng)執(zhí)行。
主要用于保留組件狀態(tài)或避免重新渲染。
keep-alive 是 Vue 的內(nèi)置組件,在組件切換過程中將狀態(tài)保留在內(nèi)存中,等再次訪問的時候,還保持著離開之前的所有狀態(tài),而不是重新初始化。也就是所謂的組件緩存。
我們知道,使用路由vue-router切換組件的時候是不保存狀態(tài)的,它進(jìn)行router.push()或router.push()或router.replace()的時候,舊組件會被銷毀,新組件會被新建,然后走一遍完整的生命周期。所以緩存經(jīng)常與router-view一起出現(xiàn):
<keep-alive> <router-view /> <!-- 所有路徑匹配到的視圖組件都會被緩存 --> </keep-alive>
被包含在 keep-alive 中創(chuàng)建的組件,會多出兩個生命周期的鉤子: activated 與 deactivated:
1. activated:在 keep-alive 組件激活時調(diào)用
2. deactivated:在 keep-alive 組件停用時調(diào)用
注意: 只有組件被 keep-alive 包裹時,這兩個生命周期函數(shù)才會被調(diào)用。這兩個鉤子在服務(wù)器端渲染期間不被調(diào)用。
應(yīng)用場景:
官網(wǎng)有一個多標(biāo)簽界面的例子,介紹的還是蠻詳細(xì)的。
我們在實際開發(fā)項目中會有一些需求,比如跳轉(zhuǎn)到詳情頁面時,需要保持列表頁的滾動條的位置,返回的時候依然在這個位置,這樣可以提高用戶體驗,這個時候就可以使用緩存組件 keep-alive 來解決。
設(shè)置了 keep-alive 緩存的組件,會多出兩個生命周期鉤子:
- 首次進(jìn)入組件時:beforeRouteEnter > beforeCreate > created > mounted > activated > ... ... > beforeRouteLeave > deactivated
- 再次進(jìn)入組件時:beforeRouteEnter > activated > ... ... > beforeRouteLeave > deactivated
可以看到,緩存的組件中 activated 鉤子函數(shù)每次都會觸發(fā),所以可以通過這個鉤子判斷,當(dāng)前組件時需要使用緩存的數(shù)據(jù)還是重新調(diào)用接口加載數(shù)據(jù)。如果未使用keep-alive 組件,則在頁面回退時會重新渲染頁面,首次進(jìn)入組件的一系列生命周期也會一一被觸發(fā)。
離開組件時,使用了 keep-alive 不會調(diào)用 beforeDestroy 和 destroyed 鉤子,因為組件沒被銷毀,被緩存起來了。所以 deactivated 這個鉤子可以看作是 beforeDestroy 和 destroyed 的代替,緩存組件銷毀的時候要做的一些操作可以放在這個里面。
需求案例
最近項目中碰到需要緩存的場景,主要還是列表頁到詳情頁的跳轉(zhuǎn),但列表頁存在多級關(guān)系,具體需求如下:

初次進(jìn)入此頁面,默認(rèn)展示左側(cè)的樹形結(jié)構(gòu)菜單,點擊某一菜單,右側(cè)加載該菜單相應(yīng)的數(shù)據(jù)列表,由列表進(jìn)入詳情內(nèi)頁,然后再返回該頁面,希望該頁面保留了用戶之前選擇的樹形菜單及數(shù)據(jù)列表。若從其他頁面進(jìn)入此頁面,則不需要緩存。
案例實踐
思路:結(jié)合 router 中設(shè)置 meta 信息,緩存列表頁。
1. 設(shè)置路由的 meta 信息
const List = () => import(/* webpackChunkName: "list" */ '../pages/List.vue')
const Detail = () => import(/* webpackChunkName: "detail" */ '../pages/Detail.vue')
{
path: 'list',
name: 'list',
component: List,
meta: {
title: '列表',
keepAlive: true, //需要緩存
isKeep: false
}
},
{
path: 'dist',
name: 'detail',
component: Detail
}
2. 修改渲染匹配視圖組件 router-view(一般是 app.vue 文件,根據(jù)實際需求會不一樣)
<div class="container">
<keep-alive>
<!-- 需要緩存的視圖組件 -->
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 不需要緩存的視圖組件 -->
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
也可以使用 keep-alive 組件的 include/exclude 屬性,include 表示要緩存的組件名(定義時的 name 屬性),而 exclude 相反,匹配到的組件不會被緩存。
<div class="container">
<keep-alive include="list">
<router-view></router-view>
</keep-alive>
</div>
3. 在需要緩存的頁面中,通過導(dǎo)航守衛(wèi) beforeRouteEnter 和 activated 鉤子判斷使用緩存還是重新渲染
beforeRouteEnter (to, from, next) {
// 只在詳情返回時做緩存
if (from.name === 'detail') {
to.meta.isKeep = true
} else {
to.meta.isKeep = false
}
next()
},
activated () {
if(this.$route.meta.isKeep) {
// 詳情返回,取緩存數(shù)據(jù)
} else {
// 重新渲染,在這里調(diào)用加載請求
}
}
此處 beforeRouteEnter 鉤子也可以使用 watch 屬性監(jiān)聽路由的變化:
watch: {
$route(to, from) {
//通過to/from.path判斷是否是需要緩存的路徑然后添加邏輯
}
}
問題:
從詳情返回列表時正常,但當(dāng)用戶在詳情頁按 F5 刷新之后,再返回列表就不能保留離開之前的狀態(tài)了,因為這時頁面重載了。
解決辦法:
在離開當(dāng)前之前,將信息儲存在 localStorage 中,當(dāng)詳情數(shù)據(jù)刷新后,手動觸發(fā)加載請求。
到此這篇關(guān)于vue緩存之keep-alive的理解和應(yīng)用詳解的文章就介紹到這了,更多相關(guān)vue keep-alive內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue中實現(xiàn)v-for循環(huán)遍歷圖片的方法
這篇文章主要介紹了Vue中實現(xiàn)v-for循環(huán)遍歷圖片的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
vue學(xué)習(xí)筆記之vue1.0和vue2.0的區(qū)別介紹
今天我們來說一說vue1.0和vue2.0的主要變化有哪些?對vue相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧2017-05-05
一文詳解vue各種權(quán)限控制與管理實現(xiàn)思路
這篇文章主要為大家介紹了vue各種權(quán)限控制與管理的實現(xiàn)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
vue項目打包并部署到Linux服務(wù)器的詳細(xì)過程
我們在會開發(fā)項目的同時,也應(yīng)該了解一下項目是如何部署到服務(wù)器的,下面這篇文章主要給大家介紹了關(guān)于vue項目打包并部署到Linux服務(wù)器的相關(guān)資料,需要的朋友可以參考下2023-01-01
vue組件中iview的modal組件爬坑問題之modal的顯示與否應(yīng)該是使用v-show
這篇文章主要介紹了vue組件中iview的modal組件爬坑問題之modal的顯示與否應(yīng)該是使用v-show,本文通過實例圖文相結(jié)合的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04

