keep-alive指定条件缓存的坑

需求

  • 编辑页面可以跳转至预览页面,预览页面返回是编辑页面不会重新加载
  • 列表页或查看页面进入编辑页面的页面需要重新加载

一下a b c 分别为:
a 列表页面
b 编辑页面
c 预览页面

走过的弯路

错误的处理方式:
a页面:

// 从列表页进入的时候将详情的keepAlive设置为false
beforeRouteLeave(to, from, next) {
    to.meta.keepAlive = false
    next()
  },

b页面:

beforeRouteEnter(to, from, next) {
    next(vm => { // 此时还没有this, 通过传入的vm, 可以充当this使用
      if (from.name === 'c') {
            // 如果从c页面过来则为true
        vm.$route.meta.keepAlive = true
      }
    })
  },
beforeRouteLeave(to, from, next) {
    if (to.name === 'c') {
      this.$route.meta.keepAlive = true
    } else {
      this.$route.meta.keepAlive = false
    }
    console.log(this.$route.meta.keepAlive, 'this.$route.meta.keepAlive=')
    next()
  },
activated() {
    // 此方法在页面缓存时会被调用,根据路由元信息决定是否重新加载数据。不加载则是上次填写完的数据
    if (!this.$route.meta.keepAlive) {
      this.init()
    }
  },

上面处理的导致的问题是: 第一次从a页面进入b, 再有b进入c时, b并没有被缓存, 因为a进入b的时候b的keepAlive为false,
从c进入b之后, b的keepAlive才变成true, 才会缓存组件.

最后发现是我想的复杂了, b的keepAlive初始值为true, 剩下的只需要判断b页面离开时要去a还是去c, 如果去a,则为false,不进行缓存, 去c则为true, 缓存b组件

正确代码实现

// 编辑页面所在的<router-view></router-view>所在的文件
// 注意: 不能和<transition></transition>一起使用
<keep-alive>
    <router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />


// 编辑页面注册路由的地方配置meta, 通过keepAlive控制适合缓存组件
{
    path: 'compile',
    component: () => import('@/views/project/compile'),
    name: 'compile',
    meta: {
        keepAlive: true,
        title: '方案编辑',
    }
}

// b页面
beforeRouteLeave(to, from, next) {
    if (to.name === 'c') {
      this.$route.meta.keepAlive = true
    } else {
      this.$route.meta.keepAlive = false
      this.clear()
    }
    console.log(this.$route.meta.keepAlive, 'this.$route.meta.keepAlive=')
    next()
  },
activated() {
    // 此方法在页面缓存时会被调用,根据路由元信息决定是否重新加载数据。不加载则是上次填写完的数据
    console.log(this.$route.meta.keepAlive, 'this.$route.meta.keepAlive======')
    if (!this.$route.meta.keepAlive) {
      this.init()
    }
  }

posted @ 2020-04-07 23:24  dear嫑闹  阅读(1677)  评论(1编辑  收藏  举报