Skip to content

10 - 组件化 (createComponent 的实现) - part 1 #10

@chenfaxiang

Description

@chenfaxiang

createComponent

项目中实例化 Vue 构造函数的时候一般传入的 render 函数如下:

import Vue from 'vue'
import App from './App.vue'

var app = new Vue({
  el: '#app',
  // 这里的 h 是 createElement 方法
  render: h => h(App)
})

即这里的 render 传入的是一个组件,而不是前面在学习数据驱动分析时的例子中写的是一个原生的标签,因此这里就会调用创建组件的方法。
在数据驱动的 vm._update 部分,学习 /src/core/vdom/create-element.jscreateElement 方法的时候它最终会调用 _createElement 方法对 tag 参数进行判断,如果是一个普通的 Html 标签则会实例化一个普通的 VNode 节点,否则通过 createComponent 方法创建一个组件 VNode

if (typeof tag === 'string') {
    let Ctor
    ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
    if (config.isReservedTag(tag)) {
      // platform built-in elements
      vnode = new VNode(
        config.parsePlatformTagName(tag), data, children,
        undefined, undefined, context
      )
    } else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
      // component
      vnode = createComponent(Ctor, data, context, children, tag)
    } else {
      // unknown or unlisted namespaced elements
      // check at runtime because it may get assigned a namespace when its
      // parent normalizes children
      vnode = new VNode(
        tag, data, children,
        undefined, undefined, context
      )
    }
  } else {
    // direct component options / constructor
    vnode = createComponent(tag, data, context, children)
  }

前面给出的示例传入的是一个 App 对象,它本质上是一个 Component 类型,即在 _createElement 方法种会直接走 else 逻辑,通过 createComponent 方法来创建 vnode

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions