vue详情页回到列表页定位到之前位置(keep-alive)

1、将需要缓存的页面路由加上meta属性:

meta:{keepAlive: true}

 

2、在app.vue里使用keepalive

    <router-view></router-view>

改为

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

3、路由守卫

router.beforeEach((to, from, next) => {if (
    ["operationRegistrationAdd"].includes(to.name) &&
    to.query.type === "details"
  ) {
    from.meta.keepAlive = true;
  } else {
    from.meta.keepAlive = false;
  }
  next();
});

如果要用局部守卫的话:

列表页:

  beforeRouteLeave(to, from, next) {
    if (
      ['operationRegistrationAdd'].includes(to.name) &&
      to.query.type === 'details'
    ) {
      from.meta.keepAlive = true
    } else {
      from.meta.keepAlive = false
    }
    next()
  }

详情页:

  beforeRouteLeave(to, from, next) {
    if (
      ['operationRegistration'].includes(to.name) &&
      from.query.type === 'details'
    ) {
      to.meta.keepAlive = true
    } else {
      to.meta.keepAlive = false
    }
    next()
  }

 

第三步用路由守卫去改变 keepAlive 的值会有bug,

优化一下:

data中声明 key: 0,绑定到组件上,当 key 值发生更改时会触发组件更新

列表页使用 activated 生命周期进行判断,如果是从 add 或 edit 回来那么重新请求接口,并且更改 key 值;路由前置守卫是当从列表页的上一级页面过来时刷新列表页的组件

  activated() {
    this.setTitle()
    const { type } = this.$route.params
    if (type === 'add' || type === 'edit') {
      this.getList()
    this.key++ } }, beforeRouteEnter(to, from, next) { if (from.name === 'register') { next((vm) => { vm.key++ }) } next() }

详情页:在路由离开时在目标路由(list)的 params 对象下添加 type 值,前提是 list 路由在进入详情时分别传了对应的 add、edit、details

  beforeRouteLeave(to, from, next) {
    to.params.type = from.query.type // 通过query传来的type
    next()
  }

 

思路:使用 keep-alive 缓存的组件,不会反复的经历 created 就会缓存下当前 list 页面,当 add、edit、details 公用一个页面时,需要传递一个 type 作为区别,在 list 页面中通过 activated 生命周期对 type 进行判断,如果是 add 或 edit 就重新请求接口,重新渲染列表;并且将滚动条的位置置顶,这个是通过改变 key 值,组件重新渲染。同时需要注意从哪个路由跳转到当前列表页的,要对那个路由进行判断,每次进来的时候滚动条都是置顶的。

 

posted @ 2021-05-27 16:36  吴小明-  阅读(1391)  评论(0编辑  收藏  举报