关于前端:请阐述keepalive组件的作用和原理

5次阅读

共计 1826 个字符,预计需要花费 5 分钟才能阅读完成。

🥕 keep-alive 作用

keep-live组件是 vue 的外部组件,次要用于缓存外部组件实例。这样做的目标在于 keep-alive 外部组件切换时,不须要从新创立组件实例,比如说应用 v -if 来决定在满足什么条件下应用哪个组件,还有就是路由切换,有个<router-view></router-view>,它会依据路由的配置,将抉择其中一个组件渲染到这个地位,当路由切换后,以后组件销毁,它又会渲染另一个组件。

如果将 keep-alive 嵌套在最外层,就像这样:

<keepAlive>
    <Component1 v-if="xxx"/>
    <Component2 v-else-if="xxx"/>
    <Component1 v-else/>
</KeepAlive>

这样 keepAlive 外部的组件来回切换时,就不须要从新创立组件实例,而是间接应用缓存中的实例,一方面能够防止创立组件带来的效率开销,另一方面能够保留组件的状态。但同时也有不好的中央,就是当组件外面蕴含大量的内容的时候会占用更多的内存空间,keepAlive 相当于是空间换工夫的做法。

keepAliveincludeexclude属性,这两个属性决定哪些组件能够进入缓存。另外还有一个 max 属性,通过它能够设置最大缓存数,当缓存的实例超过设置的数时,vue 会移除最久没有应用的组件缓存。

受 keep-alive 的影响,其外部所有嵌套的组件都具备两个生命周期钩子函数,别离是 activateddeactivated,它们别离在组件激活和失活的时候触发,第一次 activated 触发是在 mounted 之后

🌻 keep-alive 原理

在具体实现上,keep-alive 在外部保护了一个 key 数组和一个缓存对象

//keep-alive 外部申明周期函数
  created () {this.cache = Object.create(null)
    this.keys = []},

key 数组记录目前缓存的组件 key 值,如果组件没有指定 key 值,会主动生成一个惟一的 key 值

cache 对象会以 key 值为键,vnode 为值,用于缓存组件对应的虚构 DOM

在 keep-alive 的渲染函数中,其根本逻辑是判断以后渲染的 vnode 是否有对应的缓存,如果有,会从缓存中读取到对应的组件实例,如果没有就会把它缓存。

当缓存的数量超过 max 设置的数值时,keep-alive会移除 key 数组中的第一个元素

 render () {
    const slot = this.$slots.default; // 获取默认插槽
    const vnode = getFirstComponentChild(slot); // 失去插槽中第一个组件的 vnode
    const name = getComponentName(vnode.componentOptions); // 获取组件名字
   
    const {cache, keys} = this; // 获取以后的混村内对象和 key 数组
    const key: ?string = vnode.key == null
        ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
        : vnode.key; // 获取组件的 key 值,如果没有 key 值,会依照规定主动生成
      if (cache[key]) {
      // 有缓存
      // 重用组件实例
        vnode.componentInstance = cache[key].componentInstance    
        remove(keys, key); // 删除 key 值
        // 将 key 值退出到数组开端,这样是为了保障最近应用的组件在数组中靠后,次要是为了不便设置的 max 值删除很久没应用的组件
        keys.push(key)
      } else {
      // 没有缓存的则进行缓存
        cache[key] = vnode
        keys.push(key)
        // prune oldest entry
        if (this.max && keys.length > parseInt(this.max)) {
        // 超过最大缓存数量,移除第一个 key 对应的缓存
          pruneCacheEntry(cache, keys[0], keys, this._vnode)
        }
      }

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

😊 好了,以上就是我的分享,欢送大家在评论区探讨鸭~

心愿小伙伴们点赞 👍 反对一下哦~ 😘,我会更有能源的 🤞

正文完
 0