expect(vnode.props).toBe(null)
})
+ test('create from an existing vnode', () => {
+ const vnode1 = createVNode('p', { id: 'foo' })
+ const vnode2 = createVNode(vnode1, { class: 'bar' }, 'baz')
+ expect(vnode2).toMatchObject({
+ type: 'p',
+ props: {
+ id: 'foo',
+ class: 'bar'
+ },
+ children: 'baz',
+ shapeFlag: ShapeFlags.ELEMENT | ShapeFlags.TEXT_CHILDREN
+ })
+ })
+
test('vnode keys', () => {
for (const key of ['', 'a', 0, 1, NaN]) {
expect(createVNode('div', { key }).key).toBe(key)
: _createVNode) as typeof _createVNode
function _createVNode(
- type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
+ type: VNode | VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
props: (Data & VNodeProps) | null = null,
children: unknown = null,
patchFlag: number = 0,
type = Comment
}
+ if (isVNode(type)) {
+ return cloneVNode(type, props, children)
+ }
+
// class component normalization.
if (isFunction(type) && '__vccOpts' in type) {
type = type.__vccOpts
export function cloneVNode<T, U>(
vnode: VNode<T, U>,
- extraProps?: Data & VNodeProps
+ extraProps?: Data & VNodeProps | null,
+ children?: unknown
): VNode<T, U> {
const props = extraProps
? vnode.props
: vnode.props
// This is intentionally NOT using spread or extend to avoid the runtime
// key enumeration cost.
- return {
+ const cloned: VNode<T, U> = {
__v_isVNode: true,
__v_skip: true,
type: vnode.type,
el: vnode.el,
anchor: vnode.anchor
}
+ if (children) {
+ normalizeChildren(cloned, children)
+ }
+ return cloned
}
/**