写点什么

请阐述 keep-alive 组件的作用和原理

用户头像
法医
关注
发布于: 2021 年 06 月 11 日
请阐述keep-alive组件的作用和原理

🥕 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]) }
复制代码


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


希望小伙伴们点赞 👍 支持一下哦~ 😘,我会更有动力的 🤞

发布于: 2021 年 06 月 11 日阅读数: 17
用户头像

法医

关注

公众号@前端猎手 2020.07.17 加入

喜欢用写作记录自己技术成长过程

评论

发布
暂无评论
请阐述keep-alive组件的作用和原理