vue中的keep-alive的用法詳細講解

問題描述(什麼是keep-alive)

  • keep-alive顧名思義,保持活躍。保持誰活躍呢?
  • 首先咱們知道,由於vue就是組件化編程,一個.vue文件就是一個組件。就像萬事萬物同樣,都有從出生到消亡的生命週期過程,vue的組件也是同樣,也有本身的生命週期,好比create建立組件、mounted往組件上掛數據、update更新組件上掛的數據,destroy把組件實例銷燬。
  • 因此使用keep-alive就是保持組件活躍,不會被destroy銷燬掉,就一直還活着,組件沒有被銷燬掉的話,組件上掛載的數據就還存在,因此狀態就能夠保留,因此,keep-alive就能夠保持組件的狀態。
http協議的請求頭裏面也有一個keep-alive,保持http通話,這樣:Connection: keep-alive 功能雖然不同,可是思想上是同樣的即爲~保持狀態活躍

小demo,看一下keep-alive的使用效果

demo分爲上面的路由導航部分,下面的內容區部分。點擊上面的路由導航,路由視圖渲染對應的路由組件。效果圖以下:html

未使用keep-alive的效果圖

對應代碼

// #App.vue中
<template>
  <div class="box">
    <!-- 路由導航 -->
    <div class="nav">
      <router-link to="/">去home頁面</router-link>
      <router-link to="/about">去about頁面</router-link>
      <router-link to="/detail">去detail頁面</router-link>
    </div>
    <!-- 路由導航對應的內容區 -->
    <main>
      <router-view></router-view>
    </main>
  </div>
</template>

// home.vue中,放置一個複選框
<el-checkbox v-model="checked">備選項</el-checkbox>

// about.vue中,放置一個輸入框
<el-input v-model="input" placeholder="請輸入內容"></el-input>

// detail.vue中方式一個下拉框
<el-select v-model="value" placeholder="請選擇">
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value"
  >
  </el-option>
</el-select>

分析

  • 咱們發現,當咱們沒有使用keep-alive組件包裹住router-view視圖組件的時候,左邊~咱們在去home頁面勾選了,在去about頁面輸入了,在去detail頁面下拉選擇了,離開這個路由頁面,再回來時,咱們發現咱們以前作的操做,勾選、輸入、下拉選擇都不存在了,以前的狀態都沒了。緣由很簡單,當離開這個路由頁面的時候,會觸發這個路由頁面對應組件上的destroy鉤子方法,而後這個路由頁面對應的組件就被銷燬了,組件銷燬了,組件上的掛載的數據也就啥也沒有了。
  • 與此同時,咱們能夠看到在右邊的Vue.js devtools工具中,router-view視圖層始終只是home、about、detail組件來回切換,組件來回切換,其實就是組件不斷的建立、銷燬的過程。加下來咱們看看使用keep-alive的效果。

使用keep-alive的效果圖

111

對應代碼

<template>
  <div class="box">
    <!-- 路由導航 -->
    <div class="nav">
      <router-link to="/">去home頁面</router-link>
      <router-link to="/about">去about頁面</router-link>
      <router-link to="/detail">去detail頁面</router-link>
    </div>
    <!-- 路由導航對應的內容區 -->
    <main>
      <keep-alive> <!-- 使用keep-alive包了一層,就能夠緩存啦 -->
        <router-view></router-view>
      </keep-alive>
    </main>
  </div>
</template>

分析

  • 咱們給視圖層組件使用keep-alive包住之後,咱們發現,咱們勾選、輸入、下拉選擇的內容,在路由來回切換的時候,就不會丟失了,即便用keep-alive保存了以前的組件狀態
  • 與此同時,咱們能夠看到在右邊的Vue.js devtools工具中,在router-view視圖中對應的,切換過去的組件已經處於inactive狀態,inactive英文意思是不活動的、未使用的,即已經緩存的,沒有銷燬的。因此組件上的咱們所作的操做、組件的狀態就被緩存了,因此咱們勾選的、輸入的、下拉選擇的都還在。
Vue.js devtools挺好用,能夠經過谷歌下載,vue開發中的很好的工具

引出問題

看到這裏咱們發現,直接加上keep-alive的話,會把全部的router-view層級下的視圖的組件都緩存了,不過有的時候,咱們只想緩存部分,不想緩存全部的,那這怎麼辦呢?不要緊,大佬們已考慮到了,已經提早爲咱們解決好了,就是keep-alive中的include、exclude屬性vue

include和exclude指定是否緩存某些組件

include屬性

include 包含的意思。值爲字符串或正則表達式或數組。只有組件的名稱與include的值相同的纔會被緩存,即指定哪些被緩存,能夠指定多個被緩存。這裏以字符串爲例,指定多個組件緩存,語法是用逗號隔開。以下:正則表達式

// 指定home組件和about組件被緩存
<keep-alive include="home,about" >
    <router-view></router-view>
</keep-alive>

exclude屬性

exclude至關於include的反義詞,就是除了的意思,指定哪些組件不被緩存,用法和include相似,以下:編程

// 除了home組件和about組件別的都緩存,本例中就是隻緩存detail組件
<keep-alive exclude="home,about" >
    <router-view></router-view>
</keep-alive>

以include="about,detail"爲例的效果圖

語法的意思是,只緩存about和detail,別的組件不緩存。咱們看下圖的vue工具,也能夠看出來,緩存的組件,不處於對應展現的路由下,就會成爲inactive狀態。
22222後端

keep-alive除了include和exclude屬性以外,還有一個屬性就是max屬性,這個max通常狀況用的不是太多,主要目的就是控制一下被緩存的組件的個數,後緩存的就會把先緩存的給擠掉線了,也是至關於緩存優化的一中策略了。畢竟適當緩存提升用戶體驗,緩存過渡,電腦變卡。

include和exclude的屬性值是組件的名稱

include和exclude的屬性值是組件的名稱,也就是組件的name屬性值,也就是以下的name屬性值。數組

<script>
    export default {
      name: "App"
      // ...
    };
</script>

引出問題

咱們知道組件中都有對應的邏輯js部分,並且組件要發請求獲取數據的,通常狀況下,咱們都是在created或者mounted鉤子中去發請求,向後端的大佬要數據的,關於使用keep-alive後的組件的鉤子函數的問題,咱們須要注意一下緩存

使用keep-alive的鉤子函數執行順序問題

首先使用了keep-alive的組件之後,組件上就會自動加上了activated鉤子和deactivated鉤子。函數

  • activated 當組件被激活(使用)的時候觸發 能夠簡單理解爲進入這個頁面的時候觸發
  • deactivated 當組件不被使用(inactive狀態)的時候觸發 能夠簡單理解爲離開這個頁面的時候觸發

進入組件和離開組件鉤子執行順序

假設咱們只緩存home組件,咱們先看一下代碼,再在鉤子中打印出對應的順序。就知道鉤子執行的順序了,本身動手印象深入工具

  • 代碼以下組件化

    <template>
    <div>
      <el-checkbox v-model="checked">備選項</el-checkbox>
    </div>
    </template>
    <script>
    export default {
    name: "home",
    data() { return { checked: false } },
    created() {
      console.log("我是created鉤子");
    },
    mounted() {
      console.log("我是mounted鉤子");
    },
    activated() {
      console.log("我是activated鉤子");
    },
    deactivated() {
      console.log("我是deactivated鉤子");
    },
    beforeDestroy() {
      console.log("我是beforeDestroy鉤子");因此咱們能夠得出結論:
    },
    };
    </script>
  • 進入組件打印結果以下

    我是created鉤子
    我是mounted鉤子
    我是activated鉤子
  • 離開組件打印結果以下
    我是deactivated鉤子
  • 得出結論

    初始進入和離開 created ---> mounted ---> activated --> deactivated
    後續進入和離開 activated --> deactivated
因此咱們能夠在activated 和deactivated鉤子中去作一些邏輯處理,這兩個鉤子有點相似mounted和beforeDestroy鉤子,可是仍是不同。畢竟使用keep-alive不會銷燬組件

keep-alive的應用場景舉例

  • 查看錶格某條數據詳情頁,返回仍是以前的狀態,好比仍是以前的篩選結果,仍是以前的頁數等
  • 填寫的表單的內容路由跳轉返回還在,好比input框、下選擇拉框、開關切換等用戶輸入了一大把東西,跳轉再回來不能清空啊,不能讓用戶再寫一遍啊,是吧老鐵
  • 反正就是保留以前的狀態,具體應用場景其實也有不少,在此不贅述...

補充

上述咱們使用的是keep-alive包裹router-view的小案例來說解的,實際上keep-alive通常狀況下,要麼包裹router-view,要麼包裹動態組件component。代碼寫法其實是同樣的。包裹動態組件的用法以下:

<keep-alive include="home" exclude="about">
     <component :is="whichComponent"></component>
</keep-alive>
keep-alive的include和exclude屬性也支持v-bind的語法,因此也是很靈活的。
相關文章
相關標籤/搜索