Vue keep-alive按需缓存页面

2020-04-28  本文已影响0人  UU5209966

场景:在多页签模式或移动单页面应用中,我们往往希望在页签之间切换时保留前一个页签的操作(缓存页面),在关闭页签时清理缓存,以便下次打开时刷新数据

Vue提供了一个keep-alive组件,用来对组件进行缓存,而通过keep-alive组件中的include 和 exclude 属性则可以实现我们有条件地缓存页面的需求。

官网API :API

实现步骤:
(1) 通过Vuex缓存组件名称(组件名称即每个组件的name属性)
store

const page = {
    state: {
        keepAlivePage: []
    },
    mutations: {
        ADD_KEEP_ALIVE_PAGE: (state, moduleName) => {
            if (state.keepAlivePage.findIndex(item => item === moduleName) === -1) {
                state.keepAlivePage.push(moduleName)
            }
        },
        REMOVE_KEEP_ALIVE_PAGE: (state, moduleName) => {
            state.keepAlivePage.splice(state.keepAlivePage.findIndex(item => item === moduleName), 1)
        }
    },
    actions: {
        addPage({ commit }, moduleName) {
            commit('ADD_KEEP_ALIVE_PAGE', moduleName)
        },
        removePage({ commit }, moduleName) {
            commit('REMOVE_KEEP_ALIVE_PAGE', moduleName)
        }
    }
}
export default page

(2) 使用keep-alive的include属性控制组件缓存
如下面的界面将会缓存组件名为a,b的的子组件

<keep-alive include="a,b">
  <router-view></router-view>
</keep-alive>

提醒:在多级路由嵌套时,每个keep-alive都应该加上include,否则子路由会无法取消缓存

如果我要动态地缓存组件呢

<template>
   <div class="content">
          <keep-alive :include="keepAliveMultiTab">
              <router-view ref="content" />
          </keep-alive>
  </div>
</template>
<script>

export default {
  name: 'a',
  computed: {
    keepAliveMultiTab: {
      get() {
        //需要转成逗号分割的字符串
        return this.$store.page.keepAlivePage.join()
      },
      set(v) {}
    }
  },

(3) 最后我们只需要在需要设置缓存和取消缓存的地方修改keepAlivePage就行了
例如在router的beforeEach中添加要缓存的组件

router.beforeEach((to, from, next) => {
        store.dispatch('addPage', to.name)
        next()
})

在多页签组件tabs中的remove回调中取消缓存

methods: {
    ...mapActions(['addPage', 'removePage']),
    remove(targetKey) {
      for (let index = 0; index < this.pages.length; index++) {
        const element = this.pages[index]
        if (element.fullPath === targetKey) {
          this.pages.splice(index, 1)
          console.log('+++ close page' + element.name)
          this.removePage(element.name)
          break
        }
      }
  }
}

done

上一篇 下一篇

猜你喜欢

热点阅读