如何利用`keep-alive`按需緩存頁面數據


隨着項目不斷變大,頁面變多,搜索條件也隨之也越來越多,而每次跳轉頁面再返回時,之前的篩選的條件都會別清空。之前在elment-ui table組件 -- 遠程篩選排序提到過緩存,但是有所取巧,這次重新用另一種方式進行實現,或者說是更加合理一些。

場景需求

如何使頁面跳轉后回來時輸入框中輸入的值依舊存在?

初步設想

  • 利用keep-alive來緩存組件
  • 利用vuex來實時更新緩存組件的情況及緩存頁面的各類篩選條件
  • 利用vue-router來進行預判頁面是否需要緩存,從而實時更改緩存組件情況

代碼之旅開啟

  • keep-alive提供了幾個屬性,需要緩存組件名(因而需要緩存的組件都有自己的名稱,全局唯一)
    • include
    • exclude
    • max

    當前主要使用include來動態更新

  • vue-router
    • 需要在有需要緩存的頁面,在路由meta屬性添加一個字段來進行標識(首次進入)
    • beforeRouteLeave來進行預判當前頁面是否需要緩存
  • vuex
    • 緩存篩選條件(有需要在返回頁面時回顯的數據)
    • 動態緩存組件

路由

  • 通過路由名跟組件名進行綁定,取名一致(建立隱形關系)
export default [{
  path: '/keep',
  name: 'Keep', // 既是組件名又是路由名
  component: () => import('@/views/keep-alive/index.vue'),
  meta: {
    alive: true // 通過alive來確定初步是否緩存
  }
}]

vuex

  • 初始化需要緩存的組件

App.vue

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

初始化

 mounted () { 
   this.setInitActiveViews()
 }
// 獲取需要緩存的組件
getInitActiveViews (routes) {
  let views = []
  routes.forEach(route => {
    if (route.meta && route.meta.alive) {
      views.push(route.name)
    }
    if (route.children) {
      const childViews = this.getInitActiveViews(route.children)
      if (childViews.length) {
        views = [...views, ...childViews]
      }
    }
  })
  return views
},
// 存入vuex中
setInitActiveViews () {
  const alives = this.getInitActiveViews(this.$router.options.routes)
  alives.forEach(item => {
    this.$store.commit('cache/addCacheViews', item)
  })
}

至此便初步緩存組件了

  • 緩存條件

動態增刪緩存組件

在需要緩存的組件進行處理

具體的某個組件

created () {
  if (!this.$store.state.cache.cachedViews.includes(this.$options.name)) {}// 數據請求
  this.$store.commit('cache/addCacheViews', this.$options.name)
},
activated () {
  // 數據請求
},
beforeRouteLeave (to, from, next) {
  const { name } = to
  // 進入當前路由需要緩存條件
  const childRouterMap = [
    'jsonp'
  ]
  const isCache = childRouterMap.includes(name)
  if (!isCache) {
    // 清空搜索條件
    this.$store.commit('keep/deleteParams')
    // 刪除緩存
    this.$store.commit('cache/deleteViews', this.$options.name)
  }
  next()
}

此處便可以做到,只有進入jsonp路由時,頁面數據會被緩存,若是進入其他的頁面,就會被清空。同時也可以及時刷新頁面數據

總結

  • 使用beforeRouteLeave時,需要是在路由被注冊的,也就是component: **.vue該組件方可有效
  • 由於動態緩存組件一直在改動,目前只有這樣實現可以滿足需求,后期若是有更好的再進行處理
  • 條件盡可以緩存起來,使用vuex最方便了
  • 頁面數據既可以實時刷新又可以保留條件
  • 解決了頁面數據緩存,而不是粗暴地通過 v-if來觸發組件重新走一遍
  • 當前項目地址

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM