Vue原始碼解析——元件化機制
阿新 • • 發佈:2021-01-04
元件化機制
元件宣告: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 }
結論:
- 元件建立順序自上而下
- 元件掛載順序自下而上