vue3.x + vue router4.x 緩存方案

需求1:
pageA -> pageB -> pageC
緩存pageB:
pageA進入pageB,刷新頁面并緩存頁面;
pageC返回pageB,不刷新頁面

  1. 在 vuex(或其他存儲方案) 聲明兩個數(shù)組
{
    state: () => ({
        keepAliveViews: [],
        notAliveViews: [],
    }),

    mutations: {
        /**
         * 記錄需要緩存的路由視圖
         */
        saveKeepAliveViews(state, { keepAliveViews }) {
          state.keepAliveViews = keepAliveViews;
        },

        /**
         * 清除頁面緩存
         */
        clearCacheView(state, { notAliveViews }) {
          state.notAliveViews = notAliveViews;
        },
    },
}
  1. 在定義路由時,在meta中添加屬性keepAlive:true
{
    name: "pageB",
    path: "page-b",
    component: () => import("***/pageB.vue"),
    meta: {
        keepAlive: true,
    },
},
  1. 在適當位置遍歷路由表,記錄需要緩存的路由的組件名稱
// 記錄需緩存的路由/組件
const keepAliveViews = [];
router.getRoutes().forEach((routeItem) => {
    if (routeItem?.meta?.keepAlive) {
        // 組件name和路由name保持一致, 所以可以直接使用routeItem.name
        // 也可以在 meta 中添加屬性 compName 來用,或其他方案
        keepAliveViews.push(routeItem.name);
    }
});
store.commit("saveKeepAliveViews", { keepAliveViews });
  1. 在路由根組件中
//  template
<router-view v-slot="{ Component }">
    <keep-alive :include="keepAliveViews" :exclude="notAliveViews">
        <component :is="Component" />
    </keep-alive>
</router-view>
// js
const keepAliveViews = computed(() => store.state.keepAliveViews);
const notAliveViews = computed(() => store.state.notAliveViews);

keep-alive會緩存include中存在的組件,會清除exclude中的組件緩存;

  1. 手動清除組件緩存
/**
 * 清除路由(組件/頁面)緩存
 */
export function clearCacheView(destroyCompNames) {
  store.commit("clearCacheView", { notAliveViews: destroyCompNames });

  // 清除緩存后,要重置數(shù)組為空,下次才能再次緩存
  // 實際上不知道什么時候會完成緩存的清除,這里取500ms,一般滿足需求
  setTimeout(() => {
    store.commit("clearCacheView", { notAliveViews: [] });
  }, 500);
}
{
    name: "pageA",
    path: "page-a",
    component: () => import("***/pageA.vue"),
    meta: {},
    beforeEnter: () => {
      clearCacheView(["pageB"]); // 這里的"pageB"是頁面pageB的組件名稱
    },

返回pageA時,手動清除pageB的緩存;

需求2:
使用緩存頁面,大多數(shù)都是列表頁進入詳情頁,所以還需要考慮列表頁的滾動位置的問題.
即:pageC返回pageB時,pageB要保持在離開時的位置

  1. 在 vuex(或其他存儲方案) 聲明一個數(shù)組
{
    state() {
        return {
            keepAliveViewsScrollPostion: [],
        };
    },

    mutations: {
        // 設置緩存頁面滾動元素的位置
        setkeepAliveViewsScrollPostion(state, { routeName, list }) {
            const item = state.keepAliveViewsScrollPostion.find((t) => t.routeName === routeName);
            if (!item) {
                state.keepAliveViewsScrollPostion.push({ routeName, list });
            } else {
                item.list = list;
            }
        },
    },
}
  1. 在定義路由時,在meta中添加屬性scrollEls
{
    name: "pageB",
    path: "page-b",
    component: () => import("***/pageB.vue"),
    meta: {
      keepAlive: true,
      scrollEls: [".scroll-list"], // 數(shù)組形式,可添加多個可滾動元素
    },
},
  1. 在路由守衛(wèi)中
/**
 * 全局前置守衛(wèi)
 */
router.beforeEach((to, from) => {
  // 緩存頁面:記錄滾動位置
  if (from.meta.scrollEls) {
    const scrollObj: any = { routeName: from.name, list: [] };
    from.meta.scrollEls.forEach((element) => {
      const el = document.querySelector(element);
      if (el) {
        scrollObj.list.push({
          el: element,
          top: el.scrollTop,
        });
      }
    });
    store.commit("setkeepAliveViewsScrollPostion", scrollObj);
  }
});


/**
 * 全局后置鉤子
 */
router.afterEach((to, from) => {
  // 緩存頁面:滾動到指定位置
  nextTick(() => {
    if (to.meta.scrollEls) {
      const item = store.state.keepAliveViewsScrollPostion.find((t) => t.routeName === to.name);
      if (!item) return;
      item.list.forEach((item2) => {
        const el = document.querySelector(item2.el);
        if (el) {
          el.scrollTop = item2.top;
          item2.top = 0;
        }
      });
      // 使用后重置滾動位置為0
      store.commit("setkeepAliveViewsScrollPostion", item);
    }
  });
});
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市璃饱,隨后出現(xiàn)的幾起案子益兄,更是在濱河造成了極大的恐慌,老刑警劉巖盾戴,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡矫钓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門舍杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來新娜,“玉大人,你說我怎么就攤上這事既绩「帕洌” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵饲握,是天一觀的道長私杜。 經(jīng)常有香客問我蚕键,道長,這世上最難降的妖魔是什么衰粹? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任锣光,我火速辦了婚禮,結果婚禮上铝耻,老公的妹妹穿的比我還像新娘誊爹。我一直安慰自己,他們只是感情好瓢捉,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布频丘。 她就那樣靜靜地躺著,像睡著了一般泡态。 火紅的嫁衣襯著肌膚如雪搂漠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天某弦,我揣著相機與錄音状答,去河邊找鬼。 笑死刀崖,一個胖子當著我的面吹牛惊科,可吹牛的內容都是我干的。 我是一名探鬼主播亮钦,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼馆截,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜂莉?” 一聲冷哼從身側響起蜡娶,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎映穗,沒想到半個月后窖张,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡蚁滋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年宿接,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辕录。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡睦霎,死狀恐怖,靈堂內的尸體忽然破棺而出走诞,到底是詐尸還是另有隱情副女,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布蚣旱,位于F島的核電站碑幅,受9級特大地震影響戴陡,放射性物質發(fā)生泄漏。R本人自食惡果不足惜沟涨,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一猜欺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拷窜,春花似錦开皿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至懊昨,卻和暖如春窄潭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酵颁。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工嫉你, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人躏惋。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓幽污,卻偏偏與公主長得像,于是被迫代替她去往敵國和親簿姨。 傳聞我的和親對象是個殘疾皇子距误,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容

  • 1. 一個200*200的div在不同分辨率屏幕上下左右居中,用css實現(xiàn) 2. 寫一個左中右布局占滿屏幕扁位,其中左...
    造了個輪子閱讀 540評論 0 1
  • 本文目錄 1.簡述Vue的響應式原理 2.delete和Vue.delete刪除數(shù)組的區(qū)別 3.v-for循環(huán)時為...
    前端輝羽閱讀 949評論 0 12
  • 一准潭、概念介紹 Vue.js和React.js分別是目前國內和國外最火的前端框架,框架跟類庫/插件不同域仇,框架是一套完...
    劉遠舟閱讀 1,036評論 0 0
  • 安裝 vue-router 的兩種模式 一刑然、hash模式 后面的hash值變化,并不會導致瀏覽器向服務器發(fā)出請求暇务,...
    cesiuming閱讀 417評論 0 0
  • 一泼掠、父子組件傳值 基本概念在Vue中,父子組件間的數(shù)據(jù)流向可以總結為prop向下傳遞般卑,事件向上傳遞武鲁,即父組件通過p...
    北風吹_yfy閱讀 2,968評論 0 5