Vue之keep-alive页面前进刷新后退缓存

需求:现有四个页面:分类列表页A,表格列表页B,列表搜索页C,详情页D,需要实现以下链路前进刷新后退缓存

  • A—>B—>C B刷新 C—>B—>A B缓存
  • A—>B—>D B刷新 D—>B—>A B缓存
  • A—>C—>D C刷新 D—>C—>A C缓存

方案一

初始思路以及实现如下:

1、在App.vue中


<keep-alive v-if="$route.meta.keepAlive">
  <router-view/>
</keep-alive>
<router-view v-else/>

2、在路由中需要缓存的页面

{
  path: "/B",
  name: 'B',
  component: B,
  meta:{
      keepAlive: true
  }
},
{
  path: "/C",
  name: 'C',
  component: C,
  meta:{
      keepAlive: true
  }
}

3、在要缓存的页面的钩子函数中(缓存页面很多可以使用mixins)

  beforeRouteLeave (to, from, next) {
    let links = {
      'B': ['C', 'D'],
      'C': 'D'
    }
    // 判断是否开启缓存
    from.meta.keepAlive = true
    if (links[from.name].indexOf(to.name) === -1) {
      from.meta.keepAlive = false
      this.$destroy()
    }
    next()
  }

此时发现,当第一次A—>B—>C C—>B—>A,完全正常,满足需求,但是第二次A—>B—>C C—>B—>A页面并没有缓存,并且请求了数据。原因是第一次从B->A时给B设置了keepAlive为false,第二次A->B时并没有开启缓存,修改方案只需要替换上面的第二步

在路由的全局钩子函数中

router.beforeEach((to, from, next) => {
  let list = ['B', 'C'] // 存放需要缓存页面路由的name值
  if (list.indexOf(to.name) > -1) {
    to.meta.keepAlive = true
  }
  next()
})

方案二

1、在App.vue中

<keep-alive :include="includedComponents" :exclude="excludedComponents">
  <router-view/>
</keep-alive>

在computed中

computed: {
  includedComponents: state => state.includedComponents,
  excludedComponents: state => state.excludedComponents
}

2、在store中

show (state, data) {
  state.includedComponents = data
}

3、在要缓存的页面的钩子函数中(缓存页面很多可以使用mixins)

beforeRouteLeave (to, from, next) {
  let links = {
    'B': ['C', 'D'],
    'C': 'D'
  }
  if (links[from.name].indexOf(to.name) === -1) { // 不需要缓存
    this.$store.commit('show', '')
  }
  next()
},
activated () {
  // 这里的name为页面的name,最好与路由的name一致
  this.$store.commit('show', this.$route.name)
}

注意:

  • 建议在每个组件内部添加name, include匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配
  • 若将include设置空则每个页面都将会缓存
  • exclude的优先级高于include 使用exclude后,activated和deactivated不会被激活

 上一篇
vue的实用技巧 vue的实用技巧
1.善用watch的immediate属性 通常在项目中有的需求是这样子的,项目初始化的时候执行一次,然后监听它的变化,在执行 created (){ this.fetchPostList() }, watch: { searchI
2019年04月21日
下一篇 
Flutter学习 (一) Flutter学习 (一)
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
2018年12月01日
  目录