feat(runtime): 添加 h 函数和虚拟节点系统
- 实现了 h 函数用于创建虚拟节点 - 添加了 VNode 接口定义和创建逻辑 - 引入了 ShapeFlags 枚举来标记节点类型 - 实现了虚拟节点子元素标准化功能 - 在 runtime-core 中导出 h 函数 - 添加了 h 函数使用示例页面
This commit is contained in:
25
packages/runtime-core/src/h.ts
Normal file
25
packages/runtime-core/src/h.ts
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export { queuePreFlushCb } from './scheduler'
|
||||
export { watch } from './apiWatch'
|
||||
export { h } from './h'
|
||||
|
||||
43
packages/runtime-core/src/vnode.ts
Normal file
43
packages/runtime-core/src/vnode.ts
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user