美文网首页vue源码分析
Vue keep-alive源码

Vue keep-alive源码

作者: Wendy81 | 来源:发表于2020-11-05 12:52 被阅读0次
var KeepAlive = {
  name: 'keep-alive',
  abstract: true,

  props: {
    include: patternTypes,
    exclude: patternTypes,
    max: [String, Number]
  },

  created: function created () {
    this.cache = Object.create(null);
    this.keys = [];
  },

  destroyed: function destroyed () {
    for (var key in this.cache) {
      pruneCacheEntry(this.cache, key, this.keys);
    }
  },

  mounted: function mounted () {
    var this$1 = this;

    this.$watch('include', function (val) {
      pruneCache(this$1, function (name) { return matches(val, name); });
    });
    this.$watch('exclude', function (val) {
      pruneCache(this$1, function (name) { return !matches(val, name); });
    });
  },

  render: function render () {
    var slot = this.$slots.default;
    var vnode = getFirstComponentChild(slot);
    var componentOptions = vnode && vnode.componentOptions;
    if (componentOptions) {
      // check pattern
      var name = getComponentName(componentOptions);
      var ref = this;
      var include = ref.include;
      var exclude = ref.exclude;
      if (
        // not included
        (include && (!name || !matches(include, name))) ||
        // excluded
        (exclude && name && matches(exclude, name))
      ) {
        return vnode
      }

      var ref$1 = this;
      var cache = ref$1.cache;
      var keys = ref$1.keys;
      var key = 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], keys, this._vnode);
        }
      }

      vnode.data.keepAlive = true;
    }
    return vnode || (slot && slot[0])
  }
};
var builtInComponents = {
  KeepAlive: KeepAlive
};

function initGlobalAPI (Vue) {
  ......
  extend(Vue.options.components, builtInComponents);
  ......
}

上面的 extend(Vue.options.components, builtInComponents);我们知道

builtInComponents即KeepAlive也就全局组件

console.log(Vue.options.components)
{
......
KeepAlive: {name: "keep-alive", abstract: true, props: {…}, created: ƒ, 
......
}

keep-alive

  var vnode = getFirstComponentChild(slot);
  var componentOptions = vnode && vnode.componentOptions;

1.slot需为组件, 运行render时会进行cache[key] = vnode处理

    // slot是dom, <img> 则vnode为underfined
    <keep-alive>
       <img alt="Vue logo" src="./assets/logo.png">
    </keep-alive>
render: function render () {
    var slot = this.$slots.default;
    var vnode = getFirstComponentChild(slot);
    var componentOptions = vnode && vnode.componentOptions;
    if (componentOptions) {
        ......
        cache[key] = vnode;
        keys.push(key);
       ......
      }

2.slot不是组件,vnode为underfined,运行render时会进行cache[key] = vnode处理

    // slot是component, <img> 则vnode为VNode对象
    <keep-alive>
       <HelloWorld msg="Welcome to Your Vue.js App"/>
    </keep-alive>
render: function render () {
    var slot = this.$slots.default;
    var vnode = getFirstComponentChild(slot);
    var componentOptions = vnode && vnode.componentOptions;

    //vnode为undefined,则componentOptions为undefined
    if (componentOptions) {
      ......
   }

return vnode || (slot && slot[0])
//直接返回 slot,没有经过cache处理

相关文章

网友评论

    本文标题:Vue keep-alive源码

    本文链接:https://www.haomeiwen.com/subject/lwvgvktx.html