Vue中keep-alive组件的理解

前端开发 作者: 2024-08-21 16:40:01
对keep-alive组件的理解 当在组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能等问题,使用<keep-alive>包裹动态组件时,会缓存不

对keep-alive组件的理解

<keep-alive>
    <component v-bind:is="currentComponent" class="tab"></component>
</keep-alive>
export default {
    data: function() {
        return {
        
        }
    },activated: function(){
        console.log("activated");
    },deactivated: function(){
        console.log("deactivated");
    },}
  • include: 包含的组件,可以为字符串,数组,以及正则表达式,只有匹配的组件会被缓存。
  • exclude: 排除的组件,以为字符串,数组,以及正则表达式,任何匹配的组件都不会被缓存,当匹配条件同时在includeexclude存在时,以exclude优先级最高。
  • max: 缓存组件的最大值,类型为字符或者数字,可以控制缓存组件的个数,一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
<!-- 包含 逗号分隔字符串 -->
<keep-alive include="a,b">
    <component :is="show"></component>
</keep-alive>

<!-- 包含 正则表达式 使用v-bind -->
<keep-alive :include="/a|b/">
    <component :is="show"></component>
</keep-alive>

<!-- 包含 数组 使用v-bind -->
<keep-alive :include="['a','b']">
    <component :is="show"></component>
</keep-alive>

<!-- 排除 逗号分隔字符串 -->
<keep-alive exclude="a,b">
    <component :is="show"></component>
</keep-alive>

<!-- 最大缓存量 数字 -->
<keep-alive :max="10">
    <component :is="show"></component>
</keep-alive>
const vnode: VNode = getFirstComponentChild(this.$slots.default);
export default {
    created () {
        this.cache = Object.create(null)
        this.keys = []
    },mounted () {
        this.$watch('include',val => {
            pruneCache(this,name => matches(val,name))
        })
        this.$watch('exclude',name => !matches(val,name))
        })
    },}
function matches (pattern: string | RegExp | Array<string>,name: string): boolean {
    if (Array.isArray(pattern)) {
        return pattern.indexOf(name) > -1
    } else if (typeof pattern === 'string') {
        return pattern.split(',').indexOf(name) > -1
    } else if (isRegExp(pattern)) {
        return pattern.test(name)
    }
    /* istanbul ignore next */
    return false
}
function pruneCache (keepAliveInstance: any,filter: Function) {
    const { cache,keys,_vnode } = keepAliveInstance
    for (const key in cache) {
        const cachedNode: ?VNode = cache[key]
        if (cachedNode) {
            const name: ?string = getComponentName(cachedNode.componentOptions)
            if (name && !filter(name)) {
                pruneCacheEntry(cache,key,_vnode)
            }
        }
    }
}

function pruneCacheEntry (
    cache: VNodeCache,key: string,keys: Array<string>,current?: VNode
) {
    const cached = cache[key]
    if (cached && (!current || cached.tag !== current.tag)) {
        cached.componentInstance.$destroy()
    }
    cache[key] = null
    remove(keys,key)
}
export default {
  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],this._vnode)
        }
      }

      vnode.data.keepAlive = true
    }
    return vnode || (slot && slot[0])
  }
}
https://github.com/WindrunnerMax/EveryDay
https://zhuanlan.zhihu.com/p/85120544
https://cn.vuejs.org/v2/api/#keep-alive
https://juejin.im/post/6844904082038063111
https://juejin.im/post/6844903919273918477
https://juejin.im/post/6844904099272458253
https://juejin.im/post/6844904160962281479
https://fullstackbb.com/vue/deep-into-keep-alive-in-vuejs/
https://blog.liuyunzhuge.com/2020/03/20/%E7%90%86%E8%A7%A3vue%E4%B8%ADkeep-alive%E7%BB%84%E4%BB%B6%E6%BA%90%E7%A0%81/
原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_66189.html