Vue中keep-alive的深入理解和使用


什么是 keep-alive?

在平常開發中,有部分組件沒有必要多次初始化,這時,我們需要將組件進行持久化,使組件的狀態維持不變,在下一次展示時,也不會進行重新初始化組件。

也就是說,kee-alive Vue 內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染 。也就是所謂的組件緩存

基本用法

//被keep-alive包含的組件會被緩存 <keep-alive>
    <component />
</keep-alive>

keep-alive 包含的組件不會被再次初始化,也就意味着不會重走生命周期函數。
但是有時候是希望我們緩存的組件可以能夠再次進行渲染,這時 Vue 為我們解決了這個問題
被包含在 keep-alive 中創建的組件,會多出兩個生命周期的鈎子: activated deactivated

  • activated keep-alive 包含的組件再次渲染的時候觸發
  • deactivatedkeep-alive 包含的組件銷毀的時候觸發

keep-alive是一個抽象的組件,緩存的組件不會被mounted,為此提供activateddeactivated鈎子函數

在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>

防坑指南

  1. keep-alive 先匹配被包含組件的 name 字段,如果 name 不可用,則匹配當前組件 components 配置中的注冊名稱。
  2. keep-alive 不會在函數式組件中正常工作,因為它們沒有緩存實例。
  3. 當匹配條件同時在 include exclude 存在時,以 exclude 優先級最高(當前vue 2.4.2 version)。比如:包含於排除同時匹配到了組件A,那組件A不會被緩存。
  4. 包含在 keep-alive 中,但符合 exclude ,不會調用activateddeactivated

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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM