h
参数
h 可以接收 两个参数 / 三个参数
- 两个参数的情况
- h('div', h('span'))
- h('div', { style: { color: 'red' } })
- h('div','hello')
- h('div', [h('span'), h('span')])
- 三个参数情况
- h('div', {}, 'hello')
- h('div', {}, h('span'))
- h('div', {}, [h('span'), h('span')])
- 多个参数
- h('div', {}, h('span'), h('span'), h('span'), h('span'))
需要对参数进行 归一化
,归一成 type,props,children
三个参数,由 createVNode
集中处理,createVNode
要求 children
是一个「文本 / 数组」
js
function h(type, propsOrChildren?, children?){
let len = arguments.length;
// 参数
if(len == 2){
// ....
}else {
// ...
}
}
参数等于2
参数等于 2 的情况,第二个参数可能是一个对象 / 一个文本 / 一个数组 / 一个对象 / 一个 h
对于 文本/数组 来说,children 就是 文本/数组
对于对象来说,需要区分是 h('div', h('span'))
还是 h('div', { style: { color: 'red' } })
js
if (len == 2) {
// createVNode 要求孩子不是文本就是一个数组
if (isObject(propsOrChildren) && !Array.isArray(propsOrChildren)) {
if (isVNode(propsOrChildren)) {
// const VDom = h('div', h('span'))
return createVNode(type, null, [propsOrChildren]);
}
// const VDom = h('div', { style: { color: 'red' } })
return createVNode(type, propsOrChildren,null);
} else {
// const VDom = h('div','hello')
// const VDom = h('div', [h('span'), h('span')])
return createVNode(type, null, propsOrChildren);
}
}
参数大于2
js
if (len > 3) {
// const VDom = h('div', {}, h('span'), h('span'), h('span'), h('span'))
children = Array.from(arguments).slice(2);
} else {
// const VDom = h('div', {}, h('span'))
if (len == 3 && isVNode(children)) {
children = [children];
}
}
return createVNode(type, propsOrChildren, children);
createVNode
js
export function isVNode(val) {
return !!(val && val.__v_isVNode);
}
export function isSameVnode(n1, n2) {
return n1.type === n2.type && n1.key === n2.key;
}
export function createVNode(type, props, children = null) {
const shapeFlag = isString(type) ? ShapeFlags.ELEMENT : 0;
const vnode = {
shapeFlag,
__v_isVNode: true,
type,
props,
key: props && props.key,
el: null, // 每个虚拟节点都对应一个真实节点,用来存放真实节点
children,
};
if (children) {
let type = 0;
if (Array.isArray(children)) {
type = ShapeFlags.ARRAY_CHILDREN;
} else {
type = ShapeFlags.TEXT_CHILDREN;
}
vnode.shapeFlag |= type;
}
return vnode;
}
ts
export const enum ShapeFlags {
ELEMENT = 1, // 元素
FUNCTIONAL_COMPONENT = 1 << 1, // 2
STATEFUL_COMPONENT = 1 << 2, // 4
TEXT_CHILDREN = 1 << 3, // 文本孩子
ARRAY_CHILDREN = 1 << 4, // 数组孩子
SLOTS_CHILDREN = 1 << 5, // 组件的插槽
TELEPORT = 1 << 6, // 传送门组件
SUSPENSE = 1 << 7, // SUSPENSE组件
COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8, // keep-alive
COMPONENT_KEPT_ALIVE = 1 << 9,
COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT,
}
运算符 << | &
<< 无符号左移运算符,左操作数的值向左移动右操作数指定的位数。
> 0000000001 -> 1
> 0000000010; -> 2
> 0000000100 -> 4
按位或 |
按位或(|)运算符在其中一个或两个操作数对应的二进制位为 1 时,该位的结果值为 1
0000000001
|
0000000100
=
0000000101
按位与 &
按位与(&)运算符在两个操作数对应的二进位都为 1 时,该位的结果值才为 1
0000000101
&
0000000001
=
0000000001