什么是 keep-alive?
在平常開發中,有部分組件沒有必要多次初始化,這時,我們需要將組件進行持久化,使組件的狀態維持不變,在下一次展示時,也不會進行重新初始化組件。
也就是說,kee-alive 是 Vue 內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染 。也就是所謂的組件緩存
基本用法
//被keep-alive包含的組件會被緩存 <keep-alive>
<component />
</keep-alive>
被 keep-alive 包含的組件不會被再次初始化,也就意味着不會重走生命周期函數。
但是有時候是希望我們緩存的組件可以能夠再次進行渲染,這時 Vue 為我們解決了這個問題
被包含在 keep-alive 中創建的組件,會多出兩個生命周期的鈎子: activated 與 deactivated:
activated當keep-alive包含的組件再次渲染的時候觸發deactivated當keep-alive包含的組件銷毀的時候觸發
keep-alive是一個抽象的組件,緩存的組件不會被mounted,為此提供activated和deactivated鈎子函數
在2.1.0 版本后keep-alive新加入了兩個屬性: include(包含的組件緩存生效) 與 exclude(排除的組件不緩存,優先級大於include) 。
參數理解
keep-alive可以接收3個屬性做為參數進行匹配對應的組件進行緩存:
-
include包含的組件(可以為字符串,數組,以及正則表達式,只有匹配的組件會被緩存) -
exclude排除的組件(以為字符串,數組,以及正則表達式,任何匹配的組件都不會被緩存) -
max緩存組件的最大值(類型為字符或者數字,可以控制緩存組件的個數)
注:當使用正則表達式或者數組時,一定要使用v-bind
// 只緩存組件name為a或者b的組件 <keep-alive include="a,b">
<component />
</keep-alive> // 組件name為c的組件不緩存(可以保留它的狀態或避免重新渲染) <keep-alive exclude="c">
<component />
</keep-alive> // 如果同時使用include,exclude,那么exclude優先於include, 下面的例子只緩存a組件 <keep-alive include="a,b" exclude="b">
<component />
</keep-alive> // 如果緩存的組件超過了max設定的值5,那么將刪除第一個緩存的組件 <keep-alive exclude="c" max="5">
<component />
</keep-alive>
配合router使用
router-view也是一個組件,如果直接被包在keep-alive里面,那么所有路徑匹配到的視圖組件都會被緩存,如下:
<keep-alive>
<router-view>
<!-- 所有路徑匹配到的視圖組件都會被緩存! -->
</router-view>
</keep-alive>
如果只想要router-view里面的某個組件被緩存,怎么辦?
- 使用
include/exclude - 使用
meta屬性
1.使用 include (exclude例子類似)
//只有路徑匹配到的 name 為 a 組件會被緩存 <keep-alive include="a">
<router-view></router-view>
</keep-alive>
2.使用 meta 屬性
// routes 配置
export default [ { path: '/', name: 'home', component: Home, meta: { keepAlive: true // 需要被緩存
} }, { path: '/profile', name: 'profile', component: Profile, meta: { keepAlive: false // 不需要被緩存
} } ]
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 這里是會被緩存的視圖組件,比如 Home! -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 這里是不會被緩存的視圖組件,比如 Profile! -->
</router-view>
防坑指南
keep-alive先匹配被包含組件的name字段,如果name不可用,則匹配當前組件components配置中的注冊名稱。keep-alive不會在函數式組件中正常工作,因為它們沒有緩存實例。- 當匹配條件同時在
include與exclude存在時,以exclude優先級最高(當前vue 2.4.2 version)。比如:包含於排除同時匹配到了組件A,那組件A不會被緩存。 - 包含在
keep-alive中,但符合exclude,不會調用activated和deactivated。
keep-alive的生命周期
- 初次進入時:created > mounted > activated;退出后觸發 deactivated
- 再次進入:會觸發 activated;事件掛載的方法等,只執行一次的放在 mounted 中;組件每次進去執行的方法放在 activated 中

<template>
<div id="app">
<!-- <img src="./assets/logo.png"> -->
<ul>
<li><router-link to='/'>helloworld</router-link><li>
<li><router-link to='/echart'>echart</router-link><li>
<li><router-link to='/map'>map</router-link></li>
</ul>
<!-- <router-view></router-view> -->
<!-- 方法一:緩存所有的 -->
<keep-alive>
<router-view/>
</keep-alive>
<!-- 方法二 -->
<!-- 緩存模塊名為List的模塊,不會重復請求,其它模塊重復請求 -->
<keep-alive include="List">
<router-view/>
</keep-alive>
<!-- 不緩存模塊名為List的模塊,會重復請求,其它模塊緩存 -->
<keep-alive exclude="List">
<router-view/>
</keep-alive>
<!-- 方法三 -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
<script> export default { name: 'App'
// activated,deactivated這兩個生命周期函數一定是要在使用了keep-alive組件后才會有的,否則則不存在
activated(){ console.log('activated頁面打開時觸發'); }, deactivated(){ console.log('deactivated頁面關閉時觸發'); } } </script>
<style scoped>
</style>
