以下部分內容轉自博客(另外配有自己見解):https://www.cnblogs.com/nokelong/p/8116631.html
###使用keepAlive緩存頁面,一可以減少服務器請求次數,二則可以在用戶返回上一頁后記憶到上次瀏覽位置(ios端微信瀏覽器不適用,不兼容,需要另行配置:見例子(1)) ####keep-alive的介紹如下:
1,把切換出去的組件保留在內存中,可以保留它的狀態或避免重新渲染。
2、<keep-alive>是抽象組件,它自身不會渲染DOM元素,也不會出現在父組件鏈中。
3、當組件在 <keep-alive> 內被切換,它的 activated 和 deactivated 這兩個生命周期鈎子函數將會被對應執行。
注:在 2.2.0 及其更高版本中,activated 和 deactivated 將會在 <keep-alive> 樹內的所有嵌套組件中觸發。
####基本用法:使用keep-alive直接包裹組件
使用keep-alive直接包裹組件
<keep-alive>
<component :is="view"></component>
</keep-alive>
//注:<keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們。
如果需要緩存整個項目,則如下設置(直接包裹根router-view即可):
<keep-alive>
<router-view> </router-view>
</keep-alive>
####緩存部分頁面或者組件,使用route.meta屬性
1、在App.vue中設置:(根據是否需要緩存切換模式)
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
2、在router.js路由頁設置:
{
path: '/demo/demoIndex',
name: 'DemoIndex',
component: DemoIndex,
meta: {
keepAlive: true, //設置keepAlive為true,則App.vue里的$route.meta.keepAlive即為true
title:'示例頁面'
}
}
注:配置了keepAlive的頁面,在再次進入時不會重新渲染,該頁面內的組件同理不會再次渲染。
而這可能會導致該組件內的相關操作(那些每次都需要重新渲染頁面的操作:如父子組件間的傳值)不再生效。
這一點可能會導致一些莫名其妙而又無從查證的bug(我今天便遇到了,最后查出是頁面使用了keepalive導致的,2020-06-30),請知悉。
####使用新增屬性include/exclude
vue2.1.0 新增了include,exclude倆個屬性,允許組件有條件的緩存。二者都可以用逗號分隔字符串、正則表達式或一個數組來表示。
<!-- 逗號分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正則表達式 (需要 `v-bind`綁定) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 數組 (需要 `v-bind`綁定) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
注:匹配首先檢查組件自身的 name 選項,如果 name 選項不可用,則匹配它的局部注冊名稱 (父組件 components 選項的鍵值)。匿名組件不能被匹配。
####動態判斷,使用v-bind:include
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
includedComponents動態設置即可
####使用beforeRouteLeave或者afterEach中進行攔截處理
如在項目在Category組件中的設置:
beforeRouteLeave(to,from,next){
if(to.name=='DemoIndex'){
if(!from.meta.keepAlive){
from.meta.keepAlive=true
}
next()
}else{
from.meta.keepAlive=false
to.meta.keepAlive=false
next()
}
},
在beforeRouteLeave中to.name根據具體的路由進行動態緩存設置。
##生命周期變化及舉例說明 ####使用keepAlive后生命周期發生了哪些變化
正常生命周期:beforeRouteEnter --> created --> mounted --> updated -->destroyed
使用keepAlive后生命周期:
首次進入緩存頁面:beforeRouteEnter --> created --> mounted --> activated --> deactivated
再次進入緩存頁面:beforeRouteEnter --> activated --> deactivated
注:
1、這里的activated非常有用,因為頁面被緩存時,created,mounted等生命周期均失效,你若想進行一些操作,那么可以在activated內完成(下面會舉個栗子:列表頁回到上次瀏覽位置)
2、activated keep-alive組件激活時調用,該鈎子在服務器端渲染期間不被調用。
3、deactivated keep-alive組件停用時調用,該鈎子在服務端渲染期間不被調用。
####舉個栗子(1):列表頁回到上次瀏覽位置
條件:1、列表頁不可使用懶加載延遲加載數據,2、列表頁需要使用keepAlive緩存
beforeRouteLeave(to,from,next){ //離開頁面之前將高度存儲到sessionStorage。這里不建議用localStorage,因為session在關閉瀏覽器時會自動清除,而local則需要手動清除,有點麻煩。
sessionStorage.setItem('scrollH',document.getElementById('demo').scrollTop)
next()
},
activated(){ //在activated生命周期內,從sessionStorage中讀取高度值並設置到dom
if(sessionStorage.getItem('scrollH')){
document.getElementById('demo').scrollTop=sessionStorage.getItem('scrollH')
}
},