• 使用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它不是一个组件,所以也执行不了接下来的代码,只是将页面渲染了出来而已。

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

     

  • 相关阅读:
    结对
    汉堡 结对2.0
    《构建之法》第四章读后感
    复利计算单元测试
    实验一 命令解释程序的编写
    《构建之法》读后感
    复利计算 2.0
    了解和熟悉操作系统
    学习进度条
    perl的贪婪和非贪婪模式
  • 原文地址:https://www.cnblogs.com/cjechenjinge-0820/p/14607667.html
Copyright © 2020-2023  润新知