vue源码学习-初始化之initRender

2,469 阅读2分钟

接下来我们继续来学习初始化调用的初始化时调用的initRender函数

获取父节点和执行环境

vm._vnode = null // the root of the child tree
vm._staticTrees = null // v-once cached trees
const options = vm.$options
const parentVnode = vm.$vnode = options._parentVnode // the placeholder node in parent tree
const renderContext = parentVnode && parentVnode.context

开头的部分,首先获取到了父组件的vnode节点和执行环节。

组件之slot插槽

vm.$slots = resolveSlots(options._renderChildren, renderContext)
vm.$scopedSlots = emptyObject

接着进行组件的slots(插槽)的初始化.包含匿名slot,具名slot,区别在于,在组件定义中slot是否包含name属性。

// a.vue
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
// 匿名插槽的使用方式
<a>
  <div>main is here</div>
</a>
<a>
  <div slot="header">header is here</div>
  <div slot="footer">footer is here</div>
</a>

以上方法为vue2.5版本的使用方法, 在2.6.0的版本中,废弃了这种方法,改为使用v-slot进行具名操作

<a>
  <div v-slot:header>header is here</div>
  <div v-slot:footer>footer is here</div>
</a>

在slots的操作中,vue主要做了以下几点操作:

  • 若组件children子节点为空,则组件中this.$slots对象为{}空对象
  • 若组件子节点存在,则先移除slot属性,接着匿名slot设置一个默认default作为key值,存储到this.$slots对象中,具名slot则按照定义的name进行存储
  • 当定义slot的标签为template时,则获取它的子节点,进行渲染。
  • 最后删除只包含空白字符(即不包含具体内容的slot)

组件之$createElement方法

vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)

$createElement方法的主要作用是解析用户写的模板html,从而成为浏览器可以识别的格式。

以上两个方法的区别在于,当子节点只是functional组件时,返回的是一个数组格式的节点内容,同时内部已经做了解析,所以只需要简单的进行数组合并,而当子节点是