Vue源码解析——组件化机制

组件化机制

组件声明Vue.component()

initAssetRegisters(Vue) src/core/global-api/assets.js 组件注册使用extend方法将配置转换为构造函数并添加到components选项

组件实例创建及挂载:观察生成的渲染函数

"with(this){return _c('div',{attrs:{"id":"demo"}},[ _c('h1',[_v("虚拟DOM")]),_v(" "), _c('p',[_v(_s(foo))]),_v(" "),
_c('comp') // 对于组件的处理并无特殊之处
],1)}"

整体流程

首先创建的是根组件,首次_render()时,会得到整棵树的VNode结构

流程如下:

new Vue() => $mount() => vm._render() => createElement() => createComponent() => patch => createElm => createComponent()

创建自定义组件:VNode

src\core\vdom\create-element.js

_createElement实际执行VNode创建的函数,由于传入tag是非保留标签,因此判定为自定义组件通过 createComponent去创建

createComponent src/core/vdom/create-component.js 创建组件VNode,保存了上一步处理得到的组件构造函数,props,事件等

注意组件钩子安装和组件tag指定规则

创建自定义组件实例

根组件执行更新函数时,会递归创建子元素和子组件,入口createElm

createEle() core/vdom/patch.js line751

首次执行_update()时,patch()会通过createEle()创建根元素,子元素创建研究从这里开始

createComponent core/vdom/patch.js line144

自定义组件创建

// 组件实例创建、挂载
if (isDef(i = i.hook) && isDef(i = i.init)) {
     
    i(vnode, false /* hydrating */)
}
if (isDef(vnode.componentInstance)) {
     
// 元素引用指定vnode.elm,元素属性创建等 initComponent(vnode, insertedVnodeQueue) // 插入到父元素
insert(parentElm, vnode.elm, refElm)
if (isTrue(isReactivated)) {
     
        reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm)
    }
return true }

结论:

  • 组件创建顺序自上而下
  • 组件挂载顺序自下而上

你可能感兴趣的:(源码分享,Vue,vue)