vue源码--keep-alive组件的实现原理

274 阅读1分钟
  1. 使用方法

    <keep-alive>组件可接收三个属性:

    • include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
    • exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
    • max - 数字。最多可以缓存多少组件实例。达到max之后,会销毁最久没有被访问到的组件实例
    <!-- 逗号分隔字符串 -->
    <keep-alive include="a,b">
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 正则表达式 (使用 `v-bind`) -->
    <keep-alive :include="/a|b/">
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 数组 (使用 `v-bind`) -->
    <keep-alive :include="['a', 'b']">
      <component :is="view"></component>
    </keep-alive>
    
  2. 实现原理

    • 组件在created的时候会定义两个属性this.cache和this.keys

      this.cache存放被缓存的组件。this.keys存储缓存的组件的key,即this.cache的键名

      this.cache = {
        'key1': '组件1''key2': '组件2'
      }
      
    • 组件在destroyed的时候,遍历this.cache,销毁当前没有被处于渲染状态的组件并将其从cache对象中移除

    • 组件在mounted,观测include和exclude的变化,如果发生变化,则遍历this.cache, 取出每一项的name与新规则进行匹配,如果匹配不上,则销毁实例并移除。

    • Render.

      • 优先获取组件名称name,如果没有则获取tag
      • 用name跟匹配规则匹配
      • 不匹配的话无需缓存,返回vnode;
      • 匹配的话,获取组件对应的key,再看是否命中缓存
      • 命中的话,直接拿vnode的组件实例,并调整key的顺序,将其从原来的位置删掉并重新放在最后一个。
      • 没命中缓存,则将组件设置进缓存,并设置keepAlive标记位。此时还需要判断缓存组件的数量是否超过max,如果超过,则删除第一个缓存。

  3. 组件被keep-alive缓存之后再次渲染不会触发created和mounted钩子,只会触发activated和deactivated