vue3利用keepAlive緩存頁面實例詳解
場景介紹
項目中經(jīng)常會有這么一個需求,一個表單頁面,可能需要跳轉其他頁面拿到對應的數(shù)據(jù),再跳回表單頁面,但是之前填寫過的數(shù)據(jù)還在。而某些頁面跳這個表單頁面的時候,是不需要緩存,因為他是新增,如果是緩存的話,那么上次填的數(shù)據(jù),下次進入這個表單頁面的時候,那么數(shù)據(jù)還存在,明顯不符合設計的要求。
需求分析
因為項目中使用的是 vue3,所以對于頁面緩存,第一時間想到就是利用 keepAlive 做緩存,但是如果不做其他處理的話,僅僅簡單使用 keepAlive 會帶來一些問題,就像上面說的,如果上次填的數(shù)據(jù),回退到上一個頁面,再進來表單頁,那么上次填的數(shù)據(jù)還存在,那么,我們該怎么去清掉緩存,什么時候又加入緩存呢,而且清緩存和加入緩存的時機,我們又怎么把握呢,這就是我們需要解決的難題。
1. 動態(tài) include 數(shù)組
一開始,我想到的是,維護 keepAlive 的 include 數(shù)組,這個數(shù)組我使用的是 set 數(shù)據(jù)結構,因為有比較方便的增刪方法,而且不重復,代碼如下:
// useCache.ts import { ref } from "vue"; const KEEP_ALIVE_SET = ref(new Set([])); export default () => { const setKeepAlive = <T extends "add" | "delete">( operate: T, value: number ) => { KEEP_ALIVE_SET.value[operate](value); }; return { KEEP_ALIVE_SET, setKeepAlive }; };
<!-- App.vue --> <template> <router-view v-slot="{ Component }"> <transition name="router-fade" mode="out-in"> <keep-alive :include="Array.from(KEEP_ALIVE_SET)"> <component :is="Component" /> </keep-alive> </transition> </router-view> </template>
關于這里 setKeepAlive 的時機的心智負擔著實有點大,因為 add 的時候,存在著大量的頁面進行 add,即使用了路由守衛(wèi)去設置,邏輯的編寫也充斥著代碼本身,隨著頁面變多,這心智負擔也會呈現(xiàn)直線增長,并且這還會有一個 bug,當 add 緩存的時候,首次進入緩存頁面,其實他還沒緩存下來,我們都知道 keepAlive 執(zhí)行緩存,需要首次進入頁面的時候記錄下來,之后再進入的時候,判斷該頁面是否已經(jīng)加載過,就不執(zhí)行重新渲染,也就造成了,緩存能生效是在第二次進入這個頁面的時候,這明顯與我們的預想不符合,所以該方案也就 pass 掉了。
2. 時間戳 key
我們回顧下關于在 vue 中的 key 屬性:
key 這個特殊的 attribute 主要作為 Vue 的虛擬 DOM 算法提示,在比較新舊節(jié)點列表時用于識別 vnode。如果 key 相同,會最小化觸發(fā)重新渲染(達到緩存的目的),如果 key 不同,那么肯定會發(fā)生替換。
主要代碼
// useCache.ts import { ref } from "vue"; const kEEP_ALIVE_MAP = ref(new Map([])); export default () => { const setKeepAlive = (key: string, value: number) => { kEEP_ALIVE_MAP.value.set(key, value); }; return { kEEP_ALIVE_MAP, setKeepAlive }; };
<!-- App.vue --> <template> <!-- 利用緩存的時間戳key 保證頁面保鮮 --> <router-view v-slot="{ Component }"> <keep-alive :max="5"> <component :is="Component" v-if="$route.meta.keepAlive" :key="$route.meta.keepAlive ? kEEP_ALIVE_MAP.get($route.name) : $route.path" /> </keep-alive> <component :is="Component" v-if="!$route.meta.keepAlive" :key="$route.name" /> </router-view> </template>
a 頁面去到表單頁,不需要緩存:
const goAddOrdersPage = () => { // 設置時間戳key 保證每次從這個頁面跳轉,key都是最新的,進入表單頁也就一直重新渲染 setKeepAlive("AddOrder", new Date().getTime()); router.push({ name: "AddOrder" }); };
b 頁面操作完成后,回到表單頁面,需要緩存:
// 路由導航守衛(wèi) onBeforeRouteLeave((to, from, next) => { // 如果不是去的表單頁面,那么就重新更新表單頁面的key,否則的話,就直接next,這樣就可以在表單頁面用到的key還是舊的時間戳key,以此達到緩存目的 if (to.name !== "AddOrder") { setKeepAlive("AddOrder", new Date().getTime()); } next(); });
總結
在維護該 key 的時候,我使用的是一個全局變量維護,利用 hooks 的形式,在各個頁面之間進行設置,當然這只是比較簡單的一種處理方法,其實方法有很多,也可以用狀態(tài)管理器 vuex 或 pinia。注意:如果用路由 params 進行傳值,vue-router 會給出警告,目前這個方案是官方也不建議的,而且我自己也試過,params 會獲取不到值。
到此這篇關于vue3利用keepAlive緩存頁面的文章就介紹到這了,更多相關vue3用keepAlive緩存頁面內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
elementui中的el-cascader級聯(lián)選擇器的實踐
本文主要介紹了elementui中的el-cascader級聯(lián)選擇器的實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10Element-ui?DatePicker日期選擇器基礎用法示例
這篇文章主要為大家介紹了Element-ui?DatePicker日期選擇器基礎用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06vue3.0+vue-router+element-plus初實踐
這篇文章主要介紹了vue3.0+vue-router+element-plus初實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-12-12element日歷calendar組件上月、今天、下月、日歷塊點擊事件及模板源碼
這篇文章主要介紹了element日歷calendar組件上月、今天、下月、日歷塊點擊事件及模板源碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07vue循環(huán)中調用接口-promise.all();按順序執(zhí)行異步處理方式
這篇文章主要介紹了vue循環(huán)中調用接口-promise.all();按順序執(zhí)行異步處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07