記錄--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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...