Skip to content

1. createElement

createElement 是 Vue 的核心方法之一,用于创建 VNode

ts
function createElement(
  context: Component,
  tag: any,
  data: any,
  children: any,
  normalizationType: any,
  alwaysNormalize: boolean
): VNode | Array<VNode> {
  if (isArray(data) || isPrimitive(data)) {
    normalizationType = children
    children = data
    data = undefined
  }
  if (isTrue(alwaysNormalize)) {
    normalizationType = ALWAYS_NORMALIZE
  }
  return _createElement(context, tag, data, children, normalizationType)
}

2._createElement

_createElementcreateElement 的内部实现,用于创建 VNode

ts
export function _createElement(
  context: Component,
  tag?: string | Component | Function | Object,
  data?: VNodeData,
  children?: any,
  normalizationType?: number
): VNode | Array<VNode> {
  // ... 数据验证相关代码 ...

  // 1. 处理子节点规范化
  if (normalizationType === ALWAYS_NORMALIZE) {
    children = normalizeChildren(children)
  } else if (normalizationType === SIMPLE_NORMALIZE) {
    children = simpleNormalizeChildren(children)
  }

  let vnode, ns
  // 2. 创建VNode的三种主要情况
  if (typeof tag === 'string') {
    // 2.1 处理原生HTML标签
    if (config.isReservedTag(tag)) {
      vnode = new VNode(
        config.parsePlatformTagName(tag),
        data,
        children,
        undefined,
        undefined,
        context
      )
    } 
    // 2.2 处理已注册的组件
    else if (isDef((Ctor = resolveAsset(context.$options, 'components', tag)))) {
      vnode = createComponent(Ctor, data, context, children, tag)
    }
    // 2.3 处理未知标签
    else {
      vnode = new VNode(tag, data, children, undefined, undefined, context)
    }
  } else {
    // 2.4 处理组件选项/构造函数
    vnode = createComponent(tag as any, data, context, children)
  }

  // 3. 最终处理和返回
  if (isArray(vnode)) {
    return vnode
  } else if (isDef(vnode)) {
    if (isDef(ns)) applyNS(vnode, ns)
    if (isDef(data)) registerDeepBindings(data)
    return vnode
  }
  // ... 其他情况返回空VNode ...
}