美文网首页前端开发那些事儿
vue keep-alive缓存问题

vue keep-alive缓存问题

作者: 无疆wj | 来源:发表于2020-09-28 16:56 被阅读0次

    场景:
    list页面(要缓存),跳转到details页面,
    需求:
    1 从details页面返回后 list页面不刷新,并保持离开时的位置.
    2 从其他任意页面进入list页面,正常刷新

    方案:
    1 使用keep-alive包裹router-view

    <div id="app">
            <keep-alive>
                <router-view v-if="$route.meta.keepAlive"></router-view>
            </keep-alive>
    
            <!-- 这里不会被keepalive -->
            <router-view v-if="!$route.meta.keepAlive"></router-view>
    </div>
    

    2 路由注册,添加meta

     {
          path: '/list',
          name: 'List',
          component: () => import('@/pages/list.vue'),
          meta: {
            keepAlive: true
          }
    },
    

    3 list.vue中使用beforeRouteLeave钩子

    beforeRouteLeave(to, from, next) {
            if (to.name == "details") {
                from.meta.keepAlive = true
            } else {
                from.meta.keepAlive = false
            }
            next()
    },
    

    4 在组件中记录scroll滑动的距离

    this.scrollTop = document.querySelector(  ".scroll-box"  ).scrollTop
    

    keep-alive缓存组件重新激活时会触发activated周期函数,在此函数中做滚动,回到跳转details.vue前的位置

    activated() {
           document.querySelector(".scroll-box").scrollTop = this.scrollTop 
    },
    

    问题:
    list页面会由于数据的不同,重复缓存,details返回后的页面不是它的真正的上级页面
    场景还原:
    点击/list?id=01 下的01-item 前往01-item-details,返回后为/list?id=01下的页面,正常
    再点击/list?id=02 下的02-item 前往02-item-details,返回后仍为/list?id=01下的页面,异常
    原因:第二次返回list?id=02时返回的是keep-alive已缓存的组件(即第一次缓存的list组件)

    解决问题:
    手动销毁已缓存的list组件,使其每次进入list都重新缓存新的页面;
    1 使用keep-aliveexclude属性(任何名称匹配的组件都不会被缓存)

    <keep-alive :exclude="exclude" >
          <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    
    data() {
        return {
          exclude: this.$exclude,
        }
      },
    

    2 对list.vue中的beforeRouteLeave钩子函数做修改

    beforeRouteLeave(to, from, next) {
            // 离开list页面且进入的不是details页面
            if (to.name != "details") {
              // exclude添加匹配后,会自动销毁已缓存的组件
                this.$exclude.push(this.$options.name) 
              // 缓存组件销毁后要把exclude中的匹配删除,不然下次进去页面不会缓存当前组件
                setTimeout(() => {
                    for (let i = 0; i < this.$exclude.length; i++) {
                        if (this.$exclude[i] == this.$options.name) {
                            this.$exclude.splice(i, 1)
                            break
                        }
                    }
                }, 0)
            }
            next()
        },
    

    相关文章

      网友评论

        本文标题:vue keep-alive缓存问题

        本文链接:https://www.haomeiwen.com/subject/jupbektx.html