# 组件化(Component)

Vue.js的另一个核心思想:组件化

更新时间: 2019-04-11

# 什么是组件化

组件化就是把页面拆分成多个组件,每个组件依赖的CSS、JavaScript、模板、图片等放在一起开发、维护(即资源独立)。

特点:可复用、也可嵌套

# 普通VNode、组件VNode

vm._render()时(将实例渲染成VNode),执行createElement会涉及到children规范化VNode创建。那么在VNode创建时,会判断tag

  • String:当成普通VNode的目的去渲染
  • 非String:当成组件VNode的目的去渲染
import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: '#app',
    render: h => h(App)
})

// ① 此时tag是一个组件(App)
1
2
3
4
5
6
7
8
9
vnode = createComponent(Ctor, data, context, children, tag)
// ② 直接通过createComponent来创建vnode
1
2

# createComponent

src/core/vdom/create-component.js

function createComponent (
  Ctor: Class<Component> | Function | Object | void,
  data: ?VNodeData,
  context: Component,
  children: ?Array<VNode>,
  tag?: string
): VNode | Array<VNode> | void {
    // ...
}
1
2
3
4
5
6
7
8
9

主要3件事:

  • 构造子类构造函数Sub
  • 安装组件钩子函数
  • 实例化VNode

# 构造子类构造函数Sub

目的:对Sub这构造函数做了缓存,避免多次执行Vue.extend的时候对同一个子组件重复构造。

Ctor = baseCtor.extend(Ctor) // 相当于Vue.extend(Ctor),返回一个实例构造器
1

对于App.vue,导出的是一个实例选项对象

export default {
    // ...实例选项
}
1
2
3

此时,新的Ctor就是

# 安装组件钩子函数

// install component management hooks onto the placeholder node
installComponentHooks(data)
1
2

componentVNodeHooks是个对象,里面有各种钩子函数:init、prepatch、insert和destroy

installComponentHooks的过程,就是把componentVNodeHooks的钩子函数合并到data.hook里,然后在VNode执行patch过程中执行相关的钩子函数。

# 实例化VNode

const name = Ctor.options.name || tag
const vnode = new VNode(
  `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
  data, undefined, undefined, undefined, context,
  { Ctor, propsData, listeners, tag, children },
  asyncFactory
)

return vnode

// 可见,组件VNode是没有children的
1
2
3
4
5
6
7
8
9
10
11

无论是普通VNode,还是组件VNode,它们都会走到vm._update方法,然后执行patch函数。

更新时间: 6/29/2020, 10:14:56 AM