Skip to content

Commit 0800fbe

Browse files
committed
allow omitting data in createElement
1 parent 06b4703 commit 0800fbe

File tree

4 files changed

+74
-27
lines changed

4 files changed

+74
-27
lines changed

src/compiler/codegen.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function genElement (el: ASTElement): string {
6565
? genChildren(el, !el.ns && !isPlatformReservedTag(el.tag) /* asThunk */)
6666
: null
6767
code = `_h('${el.tag}'${
68-
data ? `,${data}` : children ? ',void 0' : '' // data
68+
data ? `,${data}` : '' // data
6969
}${
7070
children ? `,${children}` : '' // children
7171
})`

src/core/vdom/create-element.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,21 @@ import { normalizeChildren } from './helpers'
77
import { renderState } from '../instance/render'
88
import { warn, resolveAsset } from '../util/index'
99

10+
// wrapper function for providing a more flexible interface
11+
// without getting yelled at by flow
1012
export function createElement (
13+
tag: any,
14+
data: any,
15+
children: any
16+
): VNode | Array<VNode> | void {
17+
if (data && (Array.isArray(data) || typeof data !== 'object')) {
18+
children = data
19+
data = undefined
20+
}
21+
return _createElement.call(this, tag, data, children)
22+
}
23+
24+
function _createElement (
1125
tag?: string | Class<Component> | Function | Object,
1226
data?: VNodeData,
1327
children?: VNodeChildren | void

test/unit/modules/compiler/codegen.spec.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ describe('codegen', () => {
5757
it('generate v-if directive', () => {
5858
assertCodegen(
5959
'<p v-if="show">hello</p>',
60-
`with(this){return (show)?_h('p',void 0,["hello"]):void 0}`
60+
`with(this){return (show)?_h('p',["hello"]):void 0}`
6161
)
6262
})
6363

6464
it('generate v-else directive', () => {
6565
assertCodegen(
6666
'<div><p v-if="show">hello</p><p v-else>world</p></div>',
67-
`with(this){return _h('div',void 0,[(show)?_h('p',void 0,["hello"]):_h('p',void 0,["world"])])}`
67+
`with(this){return _h('div',[(show)?_h('p',["hello"]):_h('p',["world"])])}`
6868
)
6969
})
7070

@@ -78,7 +78,7 @@ describe('codegen', () => {
7878
it('generate ref on v-for', () => {
7979
assertCodegen(
8080
'<ul><li v-for="item in items" ref="component1"></li></ul>',
81-
`with(this){return _h('ul',void 0,[(items)&&_l((items),function(item){return _h('li',{ref:"component1",refInFor:true})})])}`
81+
`with(this){return _h('ul',[(items)&&_l((items),function(item){return _h('li',{ref:"component1",refInFor:true})})])}`
8282
)
8383
})
8484

@@ -92,7 +92,7 @@ describe('codegen', () => {
9292
it('generate template tag', () => {
9393
assertCodegen(
9494
'<template><p>{{hello}}</p></template>',
95-
`with(this){return [_h('p',void 0,[_s(hello)])]}`
95+
`with(this){return [_h('p',[_s(hello)])]}`
9696
)
9797
})
9898

@@ -114,7 +114,7 @@ describe('codegen', () => {
114114
assertCodegen(
115115
'<slot><div>hi</div></slot>',
116116
`with(this){return ($slots["default"]||[_m(0)])}`,
117-
[`with(this){return _h('div',void 0,["hi"])}`]
117+
[`with(this){return _h('div',["hi"])}`]
118118
)
119119
})
120120

@@ -275,7 +275,7 @@ describe('codegen', () => {
275275
assertCodegen(
276276
'<my-component name="mycomponent1" :msg="msg" @notify="onNotify"><div>hi</div></my-component>',
277277
`with(this){return _h('my-component',{attrs:{"msg":msg},staticAttrs:{"name":"mycomponent1"},on:{"notify":onNotify}},function(){return [_m(0)]})}`,
278-
[`with(this){return _h('div',void 0,["hi"])}`]
278+
[`with(this){return _h('div',["hi"])}`]
279279
)
280280
})
281281

@@ -294,7 +294,7 @@ describe('codegen', () => {
294294
// have "inline-template'"
295295
assertCodegen(
296296
'<my-component inline-template><p>hello world</p></my-component>',
297-
`with(this){return _h('my-component',{inlineTemplate:{render:function(){with(this){return _m(0)}},staticRenderFns:[function(){with(this){return _h('p',void 0,["hello world"])}}]}})}`
297+
`with(this){return _h('my-component',{inlineTemplate:{render:function(){with(this){return _m(0)}},staticRenderFns:[function(){with(this){return _h('p',["hello world"])}}]}})}`
298298
)
299299
// "have inline-template attrs, but not having extactly one child element
300300
assertCodegen(
@@ -313,7 +313,7 @@ describe('codegen', () => {
313313
it('not specified directives option', () => {
314314
assertCodegen(
315315
'<p v-if="show">hello world</p>',
316-
`with(this){return (show)?_h('p',void 0,["hello world"]):void 0}`,
316+
`with(this){return (show)?_h('p',["hello world"]):void 0}`,
317317
{ isReservedTag }
318318
)
319319
})
@@ -324,7 +324,7 @@ describe('codegen', () => {
324324
assertCodegen(
325325
'<div><p>hello world</p></div>',
326326
`with(this){return _m(0)}`,
327-
[`with(this){return _h('div',void 0,function(){return [_h('p',void 0,function(){return ["hello world"]})]})}`],
327+
[`with(this){return _h('div',function(){return [_h('p',function(){return ["hello world"]})]})}`],
328328
{ directives }
329329
)
330330
})

test/unit/modules/vdom/create-element.spec.js

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ describe('create-element', () => {
1313
const vm = new Vue({
1414
data: { msg: 'hello world' }
1515
})
16-
const _h = bind(createElement, vm)
16+
const h = bind(createElement, vm)
1717
renderState.activeInstance = vm
18-
const vnode = _h('p', {})
18+
const vnode = h('p', {})
1919
expect(vnode.tag).toBe('p')
2020
expect(vnode.data).toEqual({})
2121
expect(vnode.children).toBeUndefined()
@@ -34,9 +34,9 @@ describe('create-element', () => {
3434
}
3535
}
3636
})
37-
const _h = bind(createElement, vm)
37+
const h = bind(createElement, vm)
3838
renderState.activeInstance = vm
39-
const vnode = _h('my-component', { props: { msg: vm.message }})
39+
const vnode = h('my-component', { props: { msg: vm.message }})
4040
expect(vnode.tag).toMatch(/vue-component-[0-9]+/)
4141
expect(vnode.componentOptions.propsData).toEqual({ msg: vm.message })
4242
expect(vnode.children).toBeUndefined()
@@ -50,10 +50,10 @@ describe('create-element', () => {
5050
const vm = new Vue({
5151
data: { msg: 'hello world' }
5252
})
53-
const _h = bind(createElement, vm)
53+
const h = bind(createElement, vm)
5454
const tag = 'custom-tag'
5555
renderState.activeInstance = vm
56-
const vnode = _h(tag, {})
56+
const vnode = h(tag, {})
5757
expect(vnode.tag).toBe('custom-tag')
5858
expect(vnode.data).toEqual({})
5959
expect(vnode.children).toBeUndefined()
@@ -69,19 +69,19 @@ describe('create-element', () => {
6969
const vm = new Vue({
7070
data: { msg: 'hello world' }
7171
})
72-
const _h = bind(createElement, vm)
72+
const h = bind(createElement, vm)
7373
renderState.activeInstance = vm
74-
const vnode = _h(null, {})
74+
const vnode = h(null, {})
7575
expect(vnode).toEqual(emptyVNode())
7676
})
7777

7878
it('render vnode with not string tag using createElement', () => {
7979
const vm = new Vue({
8080
data: { msg: 'hello world' }
8181
})
82-
const _h = bind(createElement, vm)
82+
const h = bind(createElement, vm)
8383
renderState.activeInstance = vm
84-
const vnode = _h(Vue.extend({ // Component class
84+
const vnode = h(Vue.extend({ // Component class
8585
props: ['msg']
8686
}), { props: { msg: vm.message }})
8787
expect(vnode.tag).toMatch(/vue-component-[0-9]+/)
@@ -97,22 +97,32 @@ describe('create-element', () => {
9797
const vm = new Vue({
9898
data: { msg: 'hello world' }
9999
})
100-
const _h = bind(createElement, vm)
101-
_h('p', {})
100+
const h = bind(createElement, vm)
101+
h('p', {})
102102
expect('createElement cannot be called outside of component').toHaveBeenWarned()
103103
})
104104

105105
it('render vnode with createElement with children', () => {
106106
const vm = new Vue({})
107-
const _h = bind(createElement, vm)
107+
const h = bind(createElement, vm)
108108
renderState.activeInstance = vm
109-
const vnode = _h('p', void 0, [_h('br'), 'hello world', _h('br')])
109+
const vnode = h('p', void 0, [h('br'), 'hello world', h('br')])
110110
expect(vnode.children[0].tag).toBe('br')
111111
expect(vnode.children[1].text).toBe('hello world')
112112
expect(vnode.children[2].tag).toBe('br')
113113
})
114114

115-
it('warn message when use createElementWithChildren for component', () => {
115+
it('render vnode with children, omitting data', () => {
116+
const vm = new Vue({})
117+
const h = bind(createElement, vm)
118+
renderState.activeInstance = vm
119+
const vnode = h('p', [h('br'), 'hello world', h('br')])
120+
expect(vnode.children[0].tag).toBe('br')
121+
expect(vnode.children[1].text).toBe('hello world')
122+
expect(vnode.children[2].tag).toBe('br')
123+
})
124+
125+
it('warn message when using non-thunk children for component', () => {
116126
const vm = new Vue({
117127
data: { message: 'hello world' },
118128
components: {
@@ -121,12 +131,35 @@ describe('create-element', () => {
121131
}
122132
}
123133
})
124-
const _h = bind(createElement, vm)
134+
const h = bind(createElement, vm)
125135
renderState.activeInstance = vm
126-
const vnode = _h('my-component', { props: { msg: vm.message }}, [_h('br'), 'hello world', _h('br')])
136+
const vnode = h('my-component', { props: { msg: vm.message }}, [h('br'), 'hello world', h('br')])
127137
expect(vnode.componentOptions.children[0].tag).toBe('br')
128138
expect(vnode.componentOptions.children[1]).toBe('hello world')
129139
expect(vnode.componentOptions.children[2].tag).toBe('br')
130140
expect('A component\'s children should be a function').toHaveBeenWarned()
131141
})
142+
143+
it('render svg elements with correct namespace', () => {
144+
const vm = new Vue({})
145+
const h = bind(createElement, vm)
146+
renderState.activeInstance = vm
147+
const vnode = h('svg', [h('a')])
148+
expect(vnode.ns).toBe('svg')
149+
// should apply ns to children
150+
expect(vnode.children[0].ns).toBe('svg')
151+
})
152+
153+
it('render MathML elements with correct namespace', () => {
154+
const vm = new Vue({})
155+
const h = bind(createElement, vm)
156+
renderState.activeInstance = vm
157+
const vnode = h('math', [h('matrix')])
158+
expect(vnode.ns).toBe('math')
159+
// should apply ns to children
160+
expect(vnode.children[0].ns).toBe('math')
161+
// although not explicitly listed, elements nested under <math>
162+
// should not be treated as component
163+
expect(vnode.children[0].componentOptions).toBeUndefined()
164+
})
132165
})

0 commit comments

Comments
 (0)