vue中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相当于是空间换时间的做法。
keepAlive有include和exclude属性,这两个属性决定哪些组件可以进入缓存。另外还有一个max属性,通过它可以设置最大缓存数,当缓存的实例超过设置的数时,vue会移除最久没有使用的组件缓存。
受keep-alive的影响,其内部所有嵌套的组件都具有两个生命周期钩子函数,分别是activated和deactivated,它们分别在组件激活和失活的时候触发,第一次activated触发是在mounted之后

原理

具体实现上,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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieDYH

谢谢您嘞!我会继续加油地

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值