接下来我们继续来学习初始化调用的初始化时调用的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组件时,返回的是一个数组格式的节点内容,同时内部已经做了解析,所以只需要简单的进行数组合并,而当子节点是