13.2 从模板编译到生成vnode

按照以往分析的经验,我们会从模板的解析开始说起,第一个疑问便是:内置组件和普通组件在编译过程有区别吗?答案是没有的,不管是内置的还是用户定义组件,本质上组件在模板编译成render函数的处理方式是一致的,这里的细节不展开分析,有疑惑的可以参考前几节的原理分析。最终针对keep-aliverender函数的结果如下:

  1. with(this){···_c('keep-alive',{attrs:{"include":"child2"}},[_c(chooseTabs,{tag:"component"})],1)}

有了render函数,接下来从子开始到父会执行生成Vnode对象的过程,_c('keep-alive'···)的处理,会执行createElement生成组件Vnode,其中由于keep-alive是组件,所以会调用createComponent函数去创建子组件Vnode,createComponent之前也有分析过,这个环节和创建普通组件Vnode不同之处在于,keep-aliveVnode会剔除多余的属性内容,由于keep-alive除了slot属性之外,其他属性在组件内部并没有意义,例如class样式,<keep-alive clas="test"></keep-alive>等,所以在Vnode层剔除掉多余的属性是有意义的。而<keep-alive slot="test">的写法在2.6以上的版本也已经被废弃。(其中abstract作为抽象组件的标志,以及其作用我们后面会讲到)

  1. // 创建子组件Vnode过程
  2. function createComponent(Ctordata,context,children,tag) {
  3. // abstract是内置组件(抽象组件)的标志
  4. if (isTrue(Ctor.options.abstract)) {
  5. // 只保留slot属性,其他标签属性都被移除,在vnode对象上不再存在
  6. var slot = data.slot;
  7. data = {};
  8. if (slot) {
  9. data.slot = slot;
  10. }
  11. }
  12. }