美文网首页Vue
记一次keepAlive踩坑之旅

记一次keepAlive踩坑之旅

作者: sphenginx | 来源:发表于2019-06-20 12:40 被阅读0次

缘起

现有个vue项目, 某些页面需要缓存。 于是加了 keep-alive, 需要缓存的 router 放在 keep-alive 标签内。
标签如下:

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

后来增加了需求, 某些页面进入 A 的时候需要缓存, 某些页面进入 A 页面的时候需要重新render页面。

这时候需要 watch $route 的 from 和 to , 附实现代码如下:

watch: {
            '$route'(to, from) {
                const reInitList = ['trade', 'ha', 'deal'];
                if(reInitList.includes(from.name) && this.$route.name == 'xxx') {
                    this.init();
                }
            }
}

后来发现,在需要 re init 页面的时候,发现参数读的是之前缓存的参数,并不是当前页面的参数信息。

后来在 vue 的 issue发现大家都有这样的痛点:

https://github.com/vuejs/vue/issues/6509

性空

后来查询 keep-alive 源码发现 render 的时候 有个 key,如果为空就会读取 cid:

render () {
    const slot = this.$slots.default
    const vnode: VNode = getFirstComponentChild(slot)
    const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
    if (componentOptions) {
      // check pattern
      const name: ?string = getComponentName(componentOptions)
      const { include, exclude } = this
      if (
        // not included
        (include && (!name || !matches(include, name))) ||
        // excluded
        (exclude && name && matches(exclude, name))
      ) {
        return vnode
      }

      const { cache, keys } = this
      const key: ?string = vnode.key == null
        // same constructor may get registered as different local components
        // so cid alone is not enough (#3269)
        ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
        : vnode.key
      if (cache[key]) {
        vnode.componentInstance = cache[key].componentInstance
        // make current key freshest
        remove(keys, key)
        keys.push(key)
      } else {
        cache[key] = vnode
        keys.push(key)
        // prune oldest entry
        if (this.max && keys.length > parseInt(this.max)) {
          pruneCacheEntry(cache, keys[0], keys, this._vnode)
        }
      }

      vnode.data.keepAlive = true
    }
    return vnode || (slot && slot[0])
  }
}

于是考虑 可以把 参数信息当做key的一部分来管理,这样就不会有参数被缓存的问题了。那么 keep-alive标签可以这么写:

<keep-alive :max="20">
      <router-view v-if="$route.meta.keepAlive"  :key="$route.fullPath"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>

大功告成。

相关文章

  • 记一次keepAlive踩坑之旅

    缘起 现有个vue项目, 某些页面需要缓存。 于是加了 keep-alive, 需要缓存的 router 放...

  • http的KeepAlive详解

    KeepAlive既熟悉又陌生,踩过坑的同学都知道痛。一线运维工程师踩坑之后对于KeepAlive的总结,你不应该...

  • h5路由使用keepalive

    最近踩坑踩到keepalive了 keepalive作用:缓存组件内部状态,避免重新渲染换句话来说,当这个A页面跳...

  • [ANR Warning]onMeasure time too

    ConstraintLayout 踩坑记一次封装组合控件时的坑,我才用了集成 ConstraintLayout 来...

  • 记一次pod踩坑之旅

    把自己写的一个库开源到git 上了。。git地址。。然后朋友反馈说,不支持pod 安装,比较不方便。。所以楼主尝试...

  • RecyclerView ItemTouchHelper 拖动排

    RecyclerView ItemTouchHelper 踩坑之旅 要实现的功能: recyclerview it...

  • springboot集成swagger2深坑

    记录一次swagger2踩坑记,网上资料杂乱而不完整,自己踩的坑还算比较多,记录下自己的解决历程 一、首次来看看遇...

  • 移动端的头尾固定问题

    新起了个移动端项目,在头位固定问题上又踩了一次踩过的坑。爬起来之后弹弹土,乖乖的坐下来码字,把踩坑换来的经验教训记...

  • 踩坑之旅

    > db.user.update({"parentuser":"wyt1314"},{$set:{"parentu...

  • 踩坑之旅

    1.启动项目报错org.springframework.beans.factory.UnsatisfiedDepe...

网友评论

    本文标题:记一次keepAlive踩坑之旅

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