feat(runtime-core): support creating vnode from existing vnode
This allows passing vnode around with curried props and use it in places where VNodeType is expected, e.g. `<component :is=""/>`
This commit is contained in:
parent
359b4a30ca
commit
c9629f2692
@ -42,6 +42,20 @@ describe('vnode', () => {
|
||||
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)
|
||||
|
@ -290,7 +290,7 @@ export const createVNode = (__DEV__
|
||||
: _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,
|
||||
@ -304,6 +304,10 @@ function _createVNode(
|
||||
type = Comment
|
||||
}
|
||||
|
||||
if (isVNode(type)) {
|
||||
return cloneVNode(type, props, children)
|
||||
}
|
||||
|
||||
// class component normalization.
|
||||
if (isFunction(type) && '__vccOpts' in type) {
|
||||
type = type.__vccOpts
|
||||
@ -406,7 +410,8 @@ function _createVNode(
|
||||
|
||||
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
|
||||
@ -415,7 +420,7 @@ export function cloneVNode<T, U>(
|
||||
: 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,
|
||||
@ -452,6 +457,10 @@ export function cloneVNode<T, U>(
|
||||
el: vnode.el,
|
||||
anchor: vnode.anchor
|
||||
}
|
||||
if (children) {
|
||||
normalizeChildren(cloned, children)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user