使用keep-alive不生效的踩坑点

项目中要求针对某个页面需要添加缓存,于是用到了keep-alive,代码如下:

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

路由配置如下:
 {
        path: '/orderTable/:id',
        component: orderTable,
        name: 'orderTable',
        meta: {

            keepAlive: true // 是否缓存组件
        }
    },

怎末看都不像有问题的样子,但是二次路由切换到orderTable页面时就是不生效,

如果是keep-alive缓存的组件就会有activated 和 deactivated 两个钩子函数,当再次进入缓存的组件页面时,便触发activated和deactivated函数,不会再触发created和mounted,于是在activated函数里面打断点,当切回时并未进入该函数,说明keep-alive缓存的并不是一个组件,于是顺这个方向查看了源码如下:

........
render () {
    const slot = this.$slots.default
    const vnode: VNode = getFirstComponentChild(slot)  // 获取第一个节点元素
    const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions   // 判断当前的vnode是不是组件
    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])
  }

是不是一下就顿悟了,对于keep-alive缓存的组件,首先会读取第一个节点,然后判断它是不是一个组件,很显然我们在router-view外套了div,对于div它不是一个组件,所以也执行不了接下来的代码,只是将页面渲染了出来而已。

记录一下,谨防再犯,写的不足之处,还望指教

 

原文地址:https://www.cnblogs.com/cjechenjinge-0820/p/14607667.html