vue 路由 按需 keep-alive

banner

situation

一個常見的的場景,html

主頁 -->前進 列表頁-->前進 詳情頁,詳情頁 -->返回 主頁 -->返回 列表頁vue

咱們但願,git

從 詳情頁 -->返回 列表頁 的時候頁面的狀態是緩存,不用從新請求數據,提高用戶體驗。程序員

從 列表頁 -->返回 主頁 的時候頁面,註銷掉列表頁,以在進入不一樣的列表頁的時候,獲取最新的數據。github

task

今天 讓咱們來實現這個需求。編程

在 代碼的世界裏 解決問題的 方法 歷來都不止一種。api

好比,從數組中找到一個的值索引:數組

能夠用最基礎的 for循環 遍歷,也能夠用indexOf這種工具函數,還能夠用findIndex forEach等更語義化的高階函數來遍歷。緩存

我參考了大量的文章,爬了官方的文檔,以後,找到了好幾種辦法,下面,讓咱們來一個個分析。ruby

let's begin , 咱們開始吧。🙌

  1. 解決掉提需求的人

    😂 emm... ,相對於咱們的人生,可能代碼會更好掌控吧。

    程序員活在本身想象的王國裏

    我剛接觸電腦就發現電腦的妙處,電腦遠沒有人那麼複雜。若是你的程序寫得好,你就能夠和電腦處好關係,就能夠指揮電腦幹你 想幹的事。這個時候你是十足的主宰。 往往你坐在電腦面前,你就是在你的王國裏巡行,這樣的日子簡直就是天堂般的日子。 電腦裏的世界很大,編程人是活在本身想象的王國裏。你能夠想象到電腦裏細微到每個字節、每個比特的東西。

    -- 雷軍(沒錯就是小米那個雷軍)

    我很認同雷軍的說法,

    人生能找到一個 熱愛 的東西很可貴,你 熱愛代碼 並 專一於它的話,

    終有一天,

    它會以各類各樣的方式回報給你:工資,認同感,成就感,和你一塊兒進步,內心共鳴的人。

    你若怒放,蝴蝶自來。諸君共勉 (能騙一個相信,就少一個沙雕和我搶妹子🤣)

沙雕

  1. 睡服♂提需求的人

    😂emm..., 看着鏡子裏那張的臉,這輩子應該是沒辦法從臉上獲得任何的便利了...

富婆

  1. keep-alive

    keep-aliveVue提供的一個抽象組件,主要用於保留組件狀態或避免從新渲染。

    可是 keep-alive會把其包裹的全部組件都緩存起來。

action

咱們把需求分解成2步來實現

1.把須要緩存和不須要緩存的視圖組件區分開

思路以下圖:

router區分

  1. 寫2個 router-view 出口
<keep-alive>
    <!-- 須要緩存的視圖組件 -->
  <router-view v-if="$route.meta.keepAlive">
  </router-view>
</keep-alive>

<!-- 不須要緩存的視圖組件 -->
<router-view v-if="!$route.meta.keepAlive">
</router-view>
複製代碼
  1. Router裏定義好須要緩存的視圖組件
new Router({
    routes: [
        {
            path: '/',
            name: 'index',
            component: () => import('./views/keep-alive/index.vue'),
            meta: {
                deepth: 0.5
            }
        },
        {
            path: '/list',
            name: 'list',
            component: () => import('./views/keep-alive/list.vue'),
            meta: {
                deepth: 1
                keepAlive: true //須要被緩存
            }
        },
        {
            path: '/detail',
            name: 'detail',
            component: () => import('./views/keep-alive/detail.vue'),
            meta: {
                deepth: 2
            }
        }
    ]
})
複製代碼

2.按需keep-alive

keep-alive

include

咱們從官方文檔提供的api入手,

keep-alive組件若是設置了 include ,就只有和 include 匹配的組件會被緩存,

因此思路就是,動態修改 include 數組來實現按需緩存。

include

<keep-alive :include="include">
    <!-- 須要緩存的視圖組件 -->
  <router-view v-if="$route.meta.keepAlive">
  </router-view>
</keep-alive>

<!-- 不須要緩存的視圖組件 -->
<router-view v-if="!$route.meta.keepAlive">
</router-view>
複製代碼

讓咱們在app.vue裏監聽路由的變化,

export default {
  name: "app",
  data: () => ({
    include: []
  }),
  watch: {
    $route(to, from) {
      //若是 要 to(進入) 的頁面是須要 keepAlive 緩存的,把 name push 進 include數組
      if (to.meta.keepAlive) {
        !this.include.includes(to.name) && this.include.push(to.name);
      }
      //若是 要 form(離開) 的頁面是 keepAlive緩存的,
      //再根據 deepth 來判斷是前進仍是後退
      //若是是後退
      if (from.meta.keepAlive && to.meta.deepth < from.meta.deepth) {
        var index = this.include.indexOf(from.name);
        index !== -1 && this.include.splice(index, 1);
      }
    }
  }
};
複製代碼

須要注意的是

keep-alive須要其包裹的組件有name屬性,

咱們上面的代碼中的 pushsplice 的是 routername

因此建議你們把 routename屬性設置和 route對應componentname設成同樣的。

就是這個意思

result

讓咱們驗證一下咱們的成果

banner

vue-devtool 裏,灰色的組件,表明是緩存狀態的組件,注意觀察list的變化。

寫在最後

  1. 實現按需 keep-alive ,網上有方法,經過修改 route 配置裏的 meta裏的 keepAlive 值來實現。

直接修改 meta 的值,可能會出現上圖的狀況,keep-alive裏有一直有一個緩存的 list,正常的 rotuer-view 裏也有一個,

復現這個問題須要很長得篇幅,感興趣的朋友能夠本身去爬一下坑。

  1. 還有得方法是 經過在keep-alive 的視圖組件在退出 rotuer 的時候,調用this.$destory() 直接摧毀組件,這會致使組件無法在緩存,這個bug ,在官方issue有提到。

參考資料

官方issue

Vue項目全局配置頁面緩存,實現按需讀取緩存

關於動畫

謝謝你們的點贊和回覆,我看好多人想要demo的源碼這裏分享一下。

由於我公司目前尚未,vue的項目給我施展拳腳。我當時寫demo的時候,想的也不是動畫方面的封裝和優化,

因此分享的demo裏的代碼裏,關於動畫,會有不少重複的代碼和醜陋的實現。還請多見諒

源碼連接

關於demo動畫的一些分析,能夠看個人前2篇文章

相關文章
相關標籤/搜索