在使用基于Vue的單頁面富應用的開發(fā)中,總會面向這樣的產(chǎn)品需求,既從列表頁跳轉(zhuǎn)詳情頁面篇裁,返回時需要保存列表頁的狀態(tài)。
這種場景下赡若,若是講數(shù)據(jù)寫入到全局狀態(tài)中达布,總會面臨復雜的頁面路由判斷來清楚和存儲頁面狀態(tài)。
keep-alive簡介
相較于復雜的全局狀態(tài)管理逾冬,Vue在2.x版本中將keep-alive這一組件屬性擴展成了內(nèi)置的抽象組件<keep-alive>,它自身不會渲染一個 DOM 元素黍聂,也不會出現(xiàn)在父組件鏈中。當組件在 <keep-alive> 內(nèi)被切換身腻,它的 activated 和 deactivated 這兩個生命周期鉤子函數(shù)將會被對應執(zhí)行产还。使得被keep-alive組件包裹的組件的狀態(tài)得以保留也避免了該組件的重復渲染。
keep-alive組件應用也相當?shù)暮唵梧痔耍缦拢?/p>
<keep-alive>
<component :is="view"></component>
</keep-alive>
<!-- 多個條件判斷的子組件 -->
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>
<!-- 和 `<transition>` 一起使用 -->
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>
與vue-router的結(jié)合
當keep-alive與vue-router結(jié)合時脐区,就完全匹配我們頁面緩存保存狀態(tài)以及數(shù)據(jù)的這一個使用場景了。
<keep-alive>
<router-view>
<!-- 所有路徑匹配到的視圖組件都會被緩存她按!-->
</router-view>
</keep-alive>
將router-view作為被keep-alive包裹的組件牛隅,默認路由下的所有頁面都將被緩存,所有頁面的狀態(tài)都會被保留酌泰。
那么大家這個時候就會有個疑問媒佣,我并不想保留所有的頁面呀,我僅僅是想保留幾個業(yè)務(wù)場景陵刹,就像文頭那種由列表頁進入詳情頁默伍,再由詳情頁返回列表頁時的狀態(tài)保留。
vue在keep-alive組件提供了include 和 exclude 屬性允許組件有條件地緩存衰琐。二者都可以用逗號分隔字符串也糊、正則表達式或一個數(shù)組來表示
// 組件 app-rank
export default {
name: 'app-rank',
data () {
return {}
}
}
<keep-alive include="app-rank">
<router-view>
<!-- 只有路徑匹配到的視圖 app-rank 組件會被緩存!-->
</router-view>
</keep-alive>
當場景稍微復雜碘耳,如同級目錄之間跳轉(zhuǎn)無需保存狀態(tài)显设,僅需在跳轉(zhuǎn)詳情頁面是保存狀態(tài)時,這樣就需要動態(tài)管理keep-alive的緩存辛辨。
復雜場景下的keep-alive的使用有一下兩種方案
方案一:
<keep-alive :include="includeRoute">
<router-view>
<!-- 只有路徑匹配到的includeRoute表達式 組件會被緩存捕捂!-->
</router-view>
</keep-alive>
方案二:
路由中router.meta 屬性中增加是否緩存頁面組件的相應字段瑟枫,優(yōu)點是便于管理上下游頁面組件的緩存。
{
path: '/',
meta: {
title: '應用排行',
keepAlive: true
},
name:'appRankList',
component: (resolve) => require(['./views/app-rank.vue'], resolve)
}
路由中meta下增加keepAlive的屬性指攒,以便于route對象中讀取慷妙。
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
這樣keep-alive中出現(xiàn)的就是需要緩存的路由頁面,當需要在離開頁面前改變?nèi)ネ撁娴木彺鏍顟B(tài)時允悦,僅需要在頁面中添加beforeRouteLeave
export default {
data() {
return {
};
},
beforeRouteLeave(to, from, next) {
// 設(shè)置下一個路由的 meta
to.meta.keepAlive = false;
next();
}
}
綜上所述膝擂,Vue中頁面的緩存無需太復雜的狀態(tài)管理就可以達到緩存頁面狀態(tài)防止重復渲染的作用。