feat(runtime): 添加 h 函数和虚拟节点系统

- 实现了 h 函数用于创建虚拟节点
- 添加了 VNode 接口定义和创建逻辑
- 引入了 ShapeFlags 枚举来标记节点类型
- 实现了虚拟节点子元素标准化功能
- 在 runtime-core 中导出 h 函数
- 添加了 h 函数使用示例页面
This commit is contained in:
dj
2026-02-26 22:35:22 +08:00
parent 164bae388f
commit a3a7b8c7e4
7 changed files with 123 additions and 1 deletions

View File

@@ -0,0 +1,25 @@
import { createVNode, isVNode, VNode } from './vnode'
import { isObject } from '@vue/shared'
export function h(type: any, propsOrChildren?: any, children?: any): VNode {
const l = arguments.length
if (l === 2) {
//是对象
if (isObject(propsOrChildren) && !Array.isArray(propsOrChildren)) {
if (isVNode(propsOrChildren)) {
return createVNode(type, null, [propsOrChildren])
}
return createVNode(type, propsOrChildren, [])
} else {
//是数组
return createVNode(type, null, propsOrChildren)
}
} else {
if (l > 3) {
children = Array.prototype.slice.call(arguments, 2) //生成新的children
} else if (l === 3 && isVNode(children)) {
children = [children]
}
return createVNode(type, propsOrChildren, children)
}
}

View File

@@ -1,2 +1,3 @@
export { queuePreFlushCb } from './scheduler'
export { watch } from './apiWatch'
export { h } from './h'

View File

@@ -0,0 +1,43 @@
import { isArray, isFunction, isString, ShapeFlags } from '@vue/shared'
export interface VNode {
__v_isVNode: true
type: any
props: any
children: any
shapeFlag: number
}
export function isVNode(value): value is VNode {
return value ? value.__v_isVNode === true : false
}
export function createVNode(type, props, children): VNode {
const shapeFlag = isString(type) ? ShapeFlags.ELEMENT : 0
return createBaseVNode(type, props, children, shapeFlag)
}
function createBaseVNode(type, props, children, shapeFlag) {
const vnode = {
__v_isVNode: true,
type,
props,
shapeFlag
} as VNode
//解析/标准化当前vnode下的children
normalizeChildren(vnode, children)
return vnode
}
export function normalizeChildren(vnode: VNode, children: unknown) {
let type = 0
const { shapeFlag } = vnode
if (children == null) {
children = null
} else if (isArray(children)) {
} else if (typeof children === 'object') {
} else if (isFunction(children)) {
} else {
children = String(children)
type = ShapeFlags.TEXT_CHILDREN
}
vnode.children = children
vnode.shapeFlag |= type
}