1. 程式人生 > 其它 >vue keep-alive 元件如何清除某一個快取

vue keep-alive 元件如何清除某一個快取

vue keep-alive 元件如何清除某一個快取

keep-alive 能做什麼?

相信大家肯定訪問過帶標籤頁的網站,當你在切換選單或者切換tab標籤進行一些操作,再次切換到訪問過的選單或者tab,會儲存上一次的訪問狀態。再或者你肯定在手機上瀏覽過新聞列表頁面,那種下拉載入分頁資料,當你載入了20頁資料的時候,你看到了一篇吸引你的美圖,你便點進去檢視詳情了,看完你返回列表繼續檢視20頁的資料,正常如果沒有使用keep-alive元件,可能就會從第一頁訪問,你得瘋狂下拉20次才能接力上次的內容,我猜沒有幾個人可以忍受這種操作吧?keep-alive就可以解決這個痛點!如果這是你想要的效果請繼續往下學習。

keep-alive 介紹

此小節內容來自官方文件,如果你已經瞭解可直接看下一節內容

Props:

  • include - 字串或正則表示式。只有名稱匹配的元件會被快取。
  • exclude - 字串或正則表示式。任何名稱匹配的元件都不會被快取。
  • max - 數字。最多可以快取多少元件例項。

用法:

  1. <keep-alive> 包裹動態元件時,會快取不活動的元件例項,而不是銷燬它們。
  2. <transition> 相似,<keep-alive> 是一個抽象元件:它自身不會渲染一個 DOM 元素,也不會出現在元件的父元件鏈中。
  3. 當元件在 <keep-alive>
    內被切換,它的 activateddeactivated 這兩個生命週期鉤子函式將會被對應執行。
  4. 在 2.2.0 及其更高版本中,activated 和 deactivated 將會在 <keep-alive> 樹內的所有巢狀元件中觸發。
  5. 注意這個 <keep-alive> 要求被切換到的元件都有自己的名字,不論是通過元件的 name 選項還是區域性/全域性註冊。

主要用於保留元件狀態或避免重新渲染。

<!-- 基本 -->
<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>

注意,<keep-alive> 是用在其一個直屬的子元件被開關的情形。如果你在其中有 v-for 則不會工作。如果有上述的多個條件性的子元素,<keep-alive> 要求同時只有一個子元素被渲染。

  • include and exclude

2.1.0 新增

includeexclude prop 允許元件有條件地快取。二者都可以用逗號分隔字串、正則表示式或一個數組來表示:

<!-- 逗號分隔字串 -->
<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 選項的鍵值)。匿名元件不能被匹配。

  • max

2.5.0 新增

最多可以快取多少元件例項。一旦這個數字達到了,在新例項被建立之前,已快取元件中最久沒有被訪問的例項會被銷燬掉。

<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

<keep-alive> 不會在函式式元件中正常工作,因為它們沒有快取例項。

keep-alive 使用案例

父元件呼叫AKeepAlive子元件

<a-keep-alive>
	<router-view :key="$route.path" />
</a-keep-alive>

自己封裝一下KeepAlive元件

<template>
  <keep-alive>
    <slot></slot>
  </keep-alive>
</template>

<script>
export default {
    name:"AKeepAlive",
    props: {
      exclude: {
        type: Array,
        default: () => ([])
      },
      include: {
        type: Array,
        default: () => ([])
      }
    },
    computed: {
      
    },
    watch: {
    },
    created() {
      this.cache = Object.create(null);
      this.keys = [];
			// 在當前元件列印this物件,可以在虛擬節點(this._vnode.componentInstance)找到keep-alive的元件例項,例項上可以看到有cache和keys屬性,這裡就是快取的相關資訊
      console.log('this AKeepAlive--',this);
			// 已快取的元件詳情
			// this._vnode.componentInstance.cache
			// 已快取元件的key, include、exclude使用的也是這個key, 建議在父元件內呼叫時候 寫 :key 屬性,不寫就會呼叫元件的name
			// this._vnode.componentInstance.keys
    },
    updated() {
				// 每次切換路由需要在update生命週期列印this物件來檢視快取的資訊
        console.log('this AKeepAlive-- updated --',this);
				// 已快取的元件詳情
				// this._vnode.componentInstance.cache
				// 已快取元件的key, include、exclude使用的也是這個key, 建議在父元件內呼叫時候 寫 :key 屬性,不寫就會呼叫元件的name
				// this._vnode.componentInstance.keys
    },
};
</script>

<style>
</style>

上面程式碼列印結果:

我的訪問順序 '/subscribe' -> '/keywords',由於我呼叫封裝的AKeepAlive元件的時候寫了一個:key="$route.path",從列印結果可以看出來cache、keys的變化了吧,就是寫的路由path。

如果在父元件呼叫的時候不寫這個:key="$route.path"呢?再來看看列印結果:
父元件呼叫AKeepAlive:

<a-keep-alive >
	<router-view />
</a-keep-alive>

上面程式碼列印結果:

我的訪問順序 '/subscribe' -> '/keywords',由於這次我沒有寫key屬性,所以快取的cache裡面就是這樣了,我就從快取的vnode的tag和具體的cid(如下圖),猜測如果不寫key就會提取元件的cid進行快取,這樣肯定是不好控制,所以我還是老老實實的給寫個key屬性比較好管理

我們清除某一個快取的時候,就可以通過key找到具體的例項去銷燬了。

const element = cache[k];
// 銷燬某一個快取的例項
element.componentInstance.$destroy();
// 釋放
cache[k] = null
// 移除keys裡面對應的key
remove(keys, k)

參考:
https://www.bilibili.com/video/BV1Uf4y1N7Tn?spm_id_from=333.337.search-card.all.click (我也是看了這個視訊,收穫了不少,希望對你有幫助)