组件化

1.createComponent

在分析createElement的实现的时候,最终会调用_createElement方法,如果不是一个普通的tag标签,则会进入createComponent方法创建一个组件vnode,主要有以下几步。

  • 在createElement方法中,关键语句为vnode = createComponent(Ctor, data, context, children, tag)
  • 主要方法在src/vdom/create-components.js
  • 首先构造子类的构造函数
  • 其次安装钩子函数
  • 最后实例化vnode

构造子类构造函数

const baseCtor = context.$options._base

  // plain options object: turn it into a constructor
  if (isObject(Ctor)) {
    Ctor = baseCtor.extend(Ctor)
  }

其实,context.$options._base指向的就是vue,因此vue.extend定义在src/core/global-api/extend.js中,主要的作用就是构造一个vue的子类,是一种非常经典的原型继承发方法,把一个纯对象转换为一个继承与vue的构造器sub,并且对这个构造函数进行了缓存。

安装钩子函数

在初始化component类型的vnode过程中,会实现init,prepatch,insert,destory四个钩子函数,通过

installComponentHooks(data)

来实例化钩子函数,并且存在了data.hook中

实例化vnode

最后一步即实例化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
  )

需要注意,普通元素节点是有childern的,而组件的children是没有的,都在componentOptions这个属性里面。

2.patch

通过createComponent创建组件Vnode,接下来会走到vm.update,执行vm._patch把vnode转成真正的dom节点。

results matching ""

    No results matching ""