refactor(runtime-core): make h() support single vnode child (#181)
This commit is contained in:
parent
b7b89505eb
commit
d10b28ae0e
@ -18,8 +18,12 @@ describe('renderer: h', () => {
|
|||||||
// array
|
// array
|
||||||
expect(h('div', ['foo'])).toMatchObject(createVNode('div', null, ['foo']))
|
expect(h('div', ['foo'])).toMatchObject(createVNode('div', null, ['foo']))
|
||||||
// default slot
|
// default slot
|
||||||
|
const Component = { template: '<br />' }
|
||||||
const slot = () => {}
|
const slot = () => {}
|
||||||
expect(h('div', slot)).toMatchObject(createVNode('div', null, slot))
|
expect(h(Component, slot)).toMatchObject(createVNode(Component, null, slot))
|
||||||
|
// single vnode
|
||||||
|
const vnode = h('div')
|
||||||
|
expect(h('div', vnode)).toMatchObject(createVNode('div', null, [vnode]))
|
||||||
// text
|
// text
|
||||||
expect(h('div', 'foo')).toMatchObject(createVNode('div', null, 'foo'))
|
expect(h('div', 'foo')).toMatchObject(createVNode('div', null, 'foo'))
|
||||||
})
|
})
|
||||||
@ -28,20 +32,27 @@ describe('renderer: h', () => {
|
|||||||
// array
|
// array
|
||||||
expect(h('div', {}, ['foo'])).toMatchObject(createVNode('div', {}, ['foo']))
|
expect(h('div', {}, ['foo'])).toMatchObject(createVNode('div', {}, ['foo']))
|
||||||
// default slot
|
// default slot
|
||||||
|
const Component = { template: '<br />' }
|
||||||
const slot = () => {}
|
const slot = () => {}
|
||||||
expect(h('div', {}, slot)).toMatchObject(createVNode('div', {}, slot))
|
expect(h(Component, {}, slot)).toMatchObject(
|
||||||
|
createVNode(Component, {}, slot)
|
||||||
|
)
|
||||||
|
// single vnode
|
||||||
|
const vnode = h('div')
|
||||||
|
expect(h('div', {}, vnode)).toMatchObject(createVNode('div', {}, [vnode]))
|
||||||
// text
|
// text
|
||||||
expect(h('div', {}, 'foo')).toMatchObject(createVNode('div', {}, 'foo'))
|
expect(h('div', {}, 'foo')).toMatchObject(createVNode('div', {}, 'foo'))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('named slots with null props', () => {
|
test('named slots with null props', () => {
|
||||||
|
const Component = { template: '<br />' }
|
||||||
const slot = () => {}
|
const slot = () => {}
|
||||||
expect(
|
expect(
|
||||||
h('div', null, {
|
h(Component, null, {
|
||||||
foo: slot
|
foo: slot
|
||||||
})
|
})
|
||||||
).toMatchObject(
|
).toMatchObject(
|
||||||
createVNode('div', null, {
|
createVNode(Component, null, {
|
||||||
foo: slot
|
foo: slot
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,8 @@ import {
|
|||||||
createVNode,
|
createVNode,
|
||||||
VNodeChildren,
|
VNodeChildren,
|
||||||
Fragment,
|
Fragment,
|
||||||
Portal
|
Portal,
|
||||||
|
isVNode
|
||||||
} from './vnode'
|
} from './vnode'
|
||||||
import { isObject, isArray } from '@vue/shared'
|
import { isObject, isArray } from '@vue/shared'
|
||||||
import { Ref } from '@vue/reactivity'
|
import { Ref } from '@vue/reactivity'
|
||||||
@ -34,17 +35,19 @@ h('div', {})
|
|||||||
// type + omit props + children
|
// type + omit props + children
|
||||||
// Omit props does NOT support named slots
|
// Omit props does NOT support named slots
|
||||||
h('div', []) // array
|
h('div', []) // array
|
||||||
h('div', () => {}) // default slot
|
|
||||||
h('div', 'foo') // text
|
h('div', 'foo') // text
|
||||||
|
h('div', h('br')) // vnode
|
||||||
|
h(Component, () => {}) // default slot
|
||||||
|
|
||||||
// type + props + children
|
// type + props + children
|
||||||
h('div', {}, []) // array
|
h('div', {}, []) // array
|
||||||
h('div', {}, () => {}) // default slot
|
|
||||||
h('div', {}, {}) // named slots
|
|
||||||
h('div', {}, 'foo') // text
|
h('div', {}, 'foo') // text
|
||||||
|
h('div', {}, h('br')) // vnode
|
||||||
|
h(Component, {}, () => {}) // default slot
|
||||||
|
h(Component, {}, {}) // named slots
|
||||||
|
|
||||||
// named slots without props requires explicit `null` to avoid ambiguity
|
// named slots without props requires explicit `null` to avoid ambiguity
|
||||||
h('div', null, {})
|
h(Component, null, {})
|
||||||
**/
|
**/
|
||||||
|
|
||||||
export interface RawProps {
|
export interface RawProps {
|
||||||
@ -61,6 +64,7 @@ export type RawChildren =
|
|||||||
| string
|
| string
|
||||||
| number
|
| number
|
||||||
| boolean
|
| boolean
|
||||||
|
| VNode
|
||||||
| VNodeChildren
|
| VNodeChildren
|
||||||
| (() => any)
|
| (() => any)
|
||||||
|
|
||||||
@ -142,6 +146,10 @@ export function h(
|
|||||||
): VNode {
|
): VNode {
|
||||||
if (arguments.length === 2) {
|
if (arguments.length === 2) {
|
||||||
if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
|
if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
|
||||||
|
// single vnode without props
|
||||||
|
if (isVNode(propsOrChildren)) {
|
||||||
|
return createVNode(type, null, [propsOrChildren])
|
||||||
|
}
|
||||||
// props without children
|
// props without children
|
||||||
return createVNode(type, propsOrChildren)
|
return createVNode(type, propsOrChildren)
|
||||||
} else {
|
} else {
|
||||||
@ -149,6 +157,9 @@ export function h(
|
|||||||
return createVNode(type, null, propsOrChildren)
|
return createVNode(type, null, propsOrChildren)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (isVNode(children)) {
|
||||||
|
children = [children]
|
||||||
|
}
|
||||||
return createVNode(type, propsOrChildren, children)
|
return createVNode(type, propsOrChildren, children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ export function createBlock(
|
|||||||
return vnode
|
return vnode
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isVNode(value: any): boolean {
|
export function isVNode(value: any): value is VNode {
|
||||||
return value ? value._isVNode === true : false
|
return value ? value._isVNode === true : false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user