記錄--Vue的緩存組件 | 詳解KeepAlive

来源:https://www.cnblogs.com/smileZAZ/archive/2023/09/09/17689959.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 一. keep-alive 的作用 二. keep-alive 的原理 三. keep-alive 的應用 四. keep-alive 的刷新 五. keep-alive 頁面緩存思路 一. keep-alive 的作用 首先引用官 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

一. keep-alive 的作用

二. keep-alive 的原理

三. keep-alive 的應用

四. keep-alive 的刷新

五. keep-alive 頁面緩存思路

一. keep-alive 的作用

首先引用官網文檔介紹:keep-alive官方文檔

Vue 的 keep-alive為抽象組件,主要用於緩存內部組件數據狀態。可以將組件緩存起來併在需要時重新使用,而不是每次重新創建。這可以提高應用的性能和用戶體驗,特別是在需要頻繁切換組件時。

Props: include - 字元串或正則表達式。只有名稱匹配的組件會被緩存。 exclude - 字元串或正則表達式。任何名稱匹配的組件都不會被緩存。 max - 數字。最多可以緩存多少組件實例。

用法:

<keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們。和 <transition> 相似,<keep-alive> 是一個抽象組件:它自身不會渲染一個 DOM 元素,也不會出現在組件的父組件鏈中。

當組件在 <keep-alive> 內被切換,它的 activated 和 deactivated 這兩個生命周期鉤子函數將會被對應執行。

通常情況下,組件在銷毀時會釋放它所占用的資源,如 DOM 元素、監聽器、定時器等。而當組件需要重新使用時,需要重新創建這些資源,這會消耗額外的時間和性能。

使用 keep-alive 組件可以避免這種情況,它可以將組件緩存起來併在需要時直接使用,而不需要重新創建。這樣可以節省資源和提高性能,特別是對於那些需要頻繁切換的組件,比如 Tab 切換、路由切換等等。

另外,keep-alive 組件也提供了一些鉤子函數,可以用來在組件激活和失活時執行一些操作,比如更新數據、發送請求等等。這些鉤子函數包括:

  • activated: 組件被激活時調用,可以用來更新數據等操作。

  • deactivated: 組件被緩存時調用,可以用來清除數據等操作。

需要註意的是,keep-alive 組件只能緩存有狀態組件,不能緩存無狀態組件(比如純展示組件)。此外,如果需要緩存多個組件,需要使用 v-for 迴圈遍歷,而且每個緩存的組件必須有一個唯一的 key 屬性。

總之,keep-alive 組件可以提高應用的性能和用戶體驗,特別是在需要頻繁切換組件時。但需要註意使用時的細節和限制。

二. keep-alive 的原理

keep-alive 組件的實現原理是將被緩存的組件實例存儲到一個緩存對象中,當需要重新渲染這個組件時,會從緩存中獲取到之前的實例,並將其重新掛載到 DOM 上。

從Vue的渲染看keep-alive的渲染

Vue的渲染是從圖中render階段開始的
但keep-alive的渲染是在patch階段(構建組件樹(虛擬DOM樹),並將VNode轉換成真正DOM節點的過程)

1、在首次載入被包裹組件時,由keep-alive.js中的render函數可知,vnode.componentInstance的值是undfined,keepAlive的值是true,因為keep-alive組件作為父組件,它的render函數會先於被包裹組件執行;那麼只執行到i(vnode,false),後面的邏輯不執行;

2、再次訪問被包裹組件時,vnode.componentInstance的值就是已經緩存的組件實例,那麼會執行insert(parentElm, vnode.elm, refElm)邏輯,這樣就直接把上一次的DOM插入到父元素中。

三. keep-alive 的應用

下麵是一個簡單的例子,演示瞭如何使用 keep-alive 組件緩存一個計數器組件:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">減少</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
export default {
  props: ['count'],
  methods: {
    increment() {
      this.$emit('increment')
    },
    decrement() {
      this.$emit('decrement')
    },
    reset() {
      this.$emit('reset')
    }
  }
}
</script>

父組件使用

<template>
  <div>
    <keep-alive>
      <counter :count="count" @increment="increment" @decrement="decrement" @reset="reset" />
    </keep-alive>
    <button @click="increment">增加</button>
    <button @click="decrement">減少</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
import Counter from './Counter.vue'

export default {
  components: {
    Counter
  },
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    },
    reset() {
      this.count = 0
    }
  }
}
</script>

在這個例子中,我們創建了一個計數器組件 Counter,併在父組件中使用 keep-alive 組件來緩存它。我們還定義了一個 count 數據屬性,並將它傳遞給 Counter 組件作為一個 prop,用於展示當前的計數值。同時,我們還綁定了三個自定義事件 incrementdecrementreset,用於響應計數器的操作。

當我們點擊增加或減少按鈕時,Counter 組件的 count 屬性會發生變化,但由於它被包裹在 keep-alive 組件中,所以實際上並沒有被銷毀。當我們再次渲染 Counter 組件時,它會從緩存中獲取到之前的實例,並將其重新掛載到 DOM 上,這樣就能夠保留之前的狀態。 在上面的例子中,我們可以看到在 keep-alive 組件中只包含了一個 Counter 組件。但是,在實際應用中,我們可能需要緩存多個不同的組件,這時我們可以通過 includeexclude 屬性來指定要緩存或排除的組件。

例如,我們可以修改上面的例子,將 Counter 組件和另一個文本組件 Text 都緩存起來

<template>
  <div>
    <keep-alive :include="[Counter, Text]">
      <component :is="currentComponent" :count="count" v-on:increment="increment" v-on:decrement="decrement" v-on:reset="reset" />
    </keep-alive>
    <button @click="toggleComponent">切換</button>
    <button @click="increment">增加</button>
    <button @click="decrement">減少</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
import Counter from './Counter.vue'
import Text from './Text.vue'

export default {
  components: {
    Counter,
    Text
  },
  data() {
    return {
      count: 0,
      currentComponent: 'Counter'
    }
  },
  methods: {
    toggleComponent() {
      this.currentComponent = this.currentComponent === 'Counter' ? 'Text' : 'Counter'
    },
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    },
    reset() {
      this.count = 0
    }
  }
}
</script>

在這個例子中,我們定義了一個 currentComponent 數據屬性,用於動態切換要渲染的組件。我們還使用了 component 元素來動態渲染不同的組件。

keep-alive 組件中,我們使用了 include 屬性來指定要緩存的組件。註意,這裡傳入的是一個數組,可以包含多個組件。

同時,我們還可以使用 exclude 屬性來排除某些組件不進行緩存。例如,我們可以將 Text 組件排除在緩存之外,如下所示:

<keep-alive :include="[Counter]" :exclude="[Text]">
  <!-- 緩存 Counter 組件,排除 Text 組件 -->
</keep-alive>

總之,keep-alive 組件的作用是緩存動態組件或者組件的狀態,避免重覆渲染和銷毀組件,從而提高應用的性能。在實際應用中,我們可以通過指定要緩存或排除的組件來靈活地控制組件的緩存策略,以滿足不同的需求。

四. keep-alive 如何刷新

當使用 keep-alive 組件緩存一個組件時,如果需要在組件被緩存時執行一些操作,可以使用 activated 鉤子函數,在組件被激活(被緩存並且被展示)時觸發。如果需要在組件被緩存時清除一些數據或狀態,可以使用 deactivated 鉤子函數,在組件被停用(被緩存但不被展示)時觸發。

如果需要強制重新渲染被緩存的組件,可以使用 this.$forceUpdate() 方法。在被緩存的組件中,可以將這個方法綁定到一個按鈕上,當按鈕被點擊時,被緩存的組件會強制重新渲染。

需要註意的是,使用 this.$forceUpdate() 方法會重新渲染整個組件,包括不在 keep-alive 組件中的部分,因此需要謹慎使用,以免影響應用的性能。

除了使用 this.$forceUpdate() 方法強制重新渲染組件外,還可以使用 includeexclude 屬性來控制哪些組件應該被緩存或不被緩存。當我們需要更新一個被緩存的組件時,可以將它從緩存中排除,併在需要更新時再重新包含到緩存中。這樣可以避免無謂的重覆渲染,提高應用的性能。

綜上所述,我們可以通過使用 activateddeactivated 鉤子函數、this.$forceUpdate() 方法以及 includeexclude 屬性來控制被緩存的組件的刷新策略,以滿足不同的需求。

五. keep-alive 頁面緩存思路

功能需求描述:

  1. 頁面前進刷新,後退不刷新
  2. 動態配置可緩存的頁面
  3. 手動刷新已緩存的頁面

實現思路:動態include配置緩存組件,路由攔截判斷當前跳轉路由是否配置可緩存

<template>
  <keep-alive :include="cachedViews" :exclude="excludeViews">
    <router-view></router-view>
  </keep-alive>
</template>

動態操作include綁定值store狀態管理:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        cachedViews: [],
        excludeViews: []
    },
    mutations: {
        ADD_CACHED_VIEW: (state, payload) => {
          if (state.cachedViews.includes(payload)) return
          state.cachedViews.push(payload)
        },
        DEL_CACHED_VIEW: (state, payload) => {
          const index = state.cachedViews.indexOf(payload)
          index > -1 && state.cachedViews.splice(index, 1)
        }
    },
    actions: {
        ADD_CACHED_VIEW({ commit, }, payload) {
          commit('ADD_CACHED_VIEW', payload)
        },
        DEL_CACHED_VIEW({ commit, }, payload) {
          commit('DEL_CACHED_VIEW', payload)
        }
    }
})

export default store

在路由攔截器中實現邏輯:

1.路由導航進入時,如果配置了緩存,則記錄狀態,並實現緩存頁面

2.路由離開時,刪除緩存標識

import store from '@/store'

router.beforeEach((to, from, next) => {
   if (to.meta.keepAlive) {
     store.dispatch('ADD_CACHED_VIEW', to.name)
   }
})
<script>
export default {
  name: "B",
  beforeRouteLeave(to, from, next) {
    if (to.name != "C") {
      this.$store.dispatch('DEL_CACHED_VIEW', to.name)
    }
    next();
  },
  methods: {
  }
};
</script>

本文轉載於:

https://juejin.cn/post/7270160291413016628

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上次我們聊到 CLI 的領域交互模式。在領域交互模式中,可能存在多層次的子命令。在使用過程中如果全評記憶的話,命令少還好,多了真心記不住。頻繁 --help 也是個很麻煩的事情。如果每次按 'tab' 鍵就可以提示或補齊命令是不是很方便呢。這一節我們就來說說 'autocommplete' 如何實現... ...
  • 脫殼修複是指在進行加殼保護後的二進位程式脫殼操作後,由於加殼操作的不同,有些程式的導入表可能會受到影響,導致脫殼後程式無法正常運行。因此,需要進行修複操作,將脫殼前的導入表覆蓋到脫殼後的程式中,以使程式恢復正常運行。一般情況下,導入表被分為IAT(Import Address Table,導入地址表... ...
  • [toc] # 一、爬蟲對象-豆瓣電影短評 您好!我是[@馬哥python說](https://www.cnblogs.com/mashukui/),一名10年程式猿。 今天分享一期爬蟲案例,爬取的目標是:豆瓣上任意一部電影的短評(註意:是短評,不是影評!),以《熱烈》這部電影為例: ![爬取目標] ...
  • 在我們的SqlSugar的開發框架中,整合了Winform端、Vue3+ElementPlus的前端、以及基於UniApp+Vue+ThorUI的移動前端幾個前端處理,基本上覆蓋了我們日常的應用模式了,本篇隨筆進一步介紹前端應用的領域,研究集成WPF的應用端,循序漸進介紹基於CommunityToo... ...
  • 通過對鍵盤輸入的處理過程和設備控制器的作用的瞭解,我們可以更好地理解操作系統如何與鍵盤設備進行交互,並正確處理鍵盤輸入。同時,瞭解設備控制器的作用可以幫助我們更好地理解操作系統與外設硬體之間的通信和控制過程。 ...
  • 在Windows10/11Microsoft Store上安裝應用時,提示錯誤0x80070005,通過修改C:\Program Files\WindowsApps文件夾的許可權解決問題 ...
  • 1、前期工作 下載CentOS7鏡像:CentOS-7-x86_64-DVD-2009.iso 安裝虛擬機工具:VirtualBox 2、新建虛擬機 2.1、設置新建虛擬機的名稱、安裝路徑、類型及版本 註意:CentOS Linux 的發行版本是通過編譯 Red Hat, Inc 公開提供的 Red ...
  • 防火牆配置 # 啟動防火牆服務 systemctl start firewalld # 關閉防火牆服務 systemctl stop firewalld # 查看防火牆服務狀態 systemctl status firewalld # 開機禁用防火牆服務 systemctl disable fire ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...