Skip to content

Commit 1b3b194

Browse files
committed
merge renderElement and renderElementWithChildren
1 parent cf8aedd commit 1b3b194

File tree

9 files changed

+137
-194
lines changed

9 files changed

+137
-194
lines changed

src/compiler/codegen.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function generate (
3030
dataGenFns = pluckModuleFunction(options.modules, 'genData')
3131
platformDirectives = options.directives || {}
3232
isPlatformReservedTag = options.isReservedTag || no
33-
const code = ast ? genElement(ast) : '_h(_e("div"))'
33+
const code = ast ? genElement(ast) : '_h("div")'
3434
staticRenderFns = prevStaticRenderFns
3535
return {
3636
render: `with(this){return ${code}}`,
@@ -64,12 +64,12 @@ function genElement (el: ASTElement): string {
6464
const children = !el.inlineTemplate
6565
? genChildren(el, !el.ns && !isPlatformReservedTag(el.tag) /* asThunk */)
6666
: null
67-
code = `_h(_e('${el.tag}'${
68-
data ? `,${data}` : el.ns ? ',void 0' : '' // data
67+
code = `_h('${el.tag}'${
68+
data ? `,${data}` : (children || el.ns) ? ',void 0' : '' // data
6969
}${
70-
el.ns ? `,'${el.ns}'` : '' // namespace
71-
})${
7270
children ? `,${children}` : '' // children
71+
}${
72+
el.ns ? `,'${el.ns}'` : '' // namespace
7373
})`
7474
}
7575
// module transforms
@@ -78,7 +78,7 @@ function genElement (el: ASTElement): string {
7878
}
7979
// check keep-alive
8080
if (el.component && el.keepAlive) {
81-
code = `_h(_e("KeepAlive",{props:{child:${code}}}))`
81+
code = `_h("KeepAlive",{props:{child:${code}}})`
8282
}
8383
return code
8484
}
@@ -253,7 +253,7 @@ function genSlot (el: ASTElement): string {
253253

254254
function genComponent (el: ASTElement): string {
255255
const children = genChildren(el, true)
256-
return `_h(_e(${el.component},${genData(el)})${
256+
return `_h(${el.component},${genData(el)}${
257257
children ? `,${children}` : ''
258258
})`
259259
}

src/core/instance/render.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@ import {
88
nextTick, resolveAsset, _toString, toNumber
99
} from '../util/index'
1010

11-
import {
12-
renderElement,
13-
renderElementWithChildren,
14-
renderStatic
15-
} from '../vdom/create-element'
11+
import { createElement } from '../vdom/create-element'
1612

1713
export const renderState: {
1814
activeInstance: ?Component
@@ -26,14 +22,7 @@ export function initRender (vm: Component) {
2622
vm.$slots = {}
2723
// bind the public createElement fn to this instance
2824
// so that we get proper render context inside it.
29-
vm.$createElement = bind(function (
30-
tag?: string | Class<Component> | Function | Object,
31-
data?: VNodeData,
32-
children?: VNodeChildren,
33-
namespace?: string
34-
) {
35-
return this._h(this._e(tag, data, namespace), children)
36-
}, vm)
25+
vm.$createElement = bind(createElement, vm)
3726
if (vm.$options.el) {
3827
vm.$mount(vm.$options.el)
3928
}
@@ -88,22 +77,29 @@ export function renderMixin (Vue: Class<Component>) {
8877
}
8978

9079
// shorthands used in render functions
91-
Vue.prototype._h = renderElementWithChildren
92-
Vue.prototype._e = renderElement
93-
Vue.prototype._m = renderStatic
80+
Vue.prototype._h = createElement
9481
// toString for mustaches
9582
Vue.prototype._s = _toString
9683
// number conversion
9784
Vue.prototype._n = toNumber
9885

86+
//
87+
Vue.prototype._m = function renderStatic (index?: number): Object | void {
88+
return this._staticTrees[index] || (
89+
this._staticTrees[index] = this.$options.staticRenderFns[index].call(
90+
this._renderProxy
91+
)
92+
)
93+
}
94+
9995
// filter resolution helper
10096
const identity = _ => _
101-
Vue.prototype._f = function (id) {
97+
Vue.prototype._f = function resolveFilter (id) {
10298
return resolveAsset(this.$options, 'filters', id, true) || identity
10399
}
104100

105101
// render v-for
106-
Vue.prototype._l = function (
102+
Vue.prototype._l = function renderList (
107103
val: any,
108104
render: () => VNode
109105
): ?Array<VNode> {
@@ -130,7 +126,7 @@ export function renderMixin (Vue: Class<Component>) {
130126
}
131127

132128
// apply v-bind object
133-
Vue.prototype._b = function (vnode: VNodeWithData, value: any) {
129+
Vue.prototype._b = function bindProps (vnode: VNodeWithData, value: any) {
134130
if (value) {
135131
if (!isObject(value)) {
136132
process.env.NODE_ENV !== 'production' && warn(
@@ -153,15 +149,17 @@ export function renderMixin (Vue: Class<Component>) {
153149
}
154150

155151
// expose v-on keyCodes
156-
Vue.prototype._k = key => config.keyCodes[key]
152+
Vue.prototype._k = function getKeyCodes (key: string): any {
153+
return config.keyCodes[key]
154+
}
157155
}
158156

159157
function resolveSlots (
160158
vm: Component,
161159
renderChildren: Array<any> | () => Array<any> | string
162160
) {
163161
if (renderChildren) {
164-
const children = normalizeChildren(renderChildren)
162+
const children = normalizeChildren(renderChildren) || []
165163
const slots = {}
166164
const defaultSlot = []
167165
let name, child

src/core/vdom/create-component.js

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import Vue from '../instance/index'
44
import VNode from './vnode'
5+
import { normalizeChildren } from './helpers'
56
import { callHook } from '../instance/lifecycle'
67
import { warn, isObject, hasOwn, hyphenate } from '../util/index'
78

@@ -14,14 +15,27 @@ export function createComponent (
1415
parent: Component,
1516
context: Component,
1617
host: ?Component,
18+
children?: VNodeChildren,
1719
tag?: string
1820
): VNode | void {
21+
// ensure children is a thunk
22+
if (process.env.NODE_ENV !== 'production' &&
23+
children && typeof children !== 'function') {
24+
warn(
25+
'A component\'s children should be a function that returns the ' +
26+
'children array. This allows the component to track the children ' +
27+
'dependencies and optimizes re-rendering.'
28+
)
29+
}
30+
1931
if (!Ctor) {
2032
return
2133
}
34+
2235
if (isObject(Ctor)) {
2336
Ctor = Vue.extend(Ctor)
2437
}
38+
2539
if (typeof Ctor !== 'function') {
2640
if (process.env.NODE_ENV !== 'production') {
2741
warn(`Invalid Component definition: ${Ctor}`, parent)
@@ -50,15 +64,22 @@ export function createComponent (
5064

5165
data = data || {}
5266

53-
// merge component management hooks onto the placeholder node
54-
// only need to do this if this is not a functional component
55-
if (!Ctor.options.functional) {
56-
mergeHooks(data)
57-
}
58-
5967
// extract props
6068
const propsData = extractProps(data, Ctor)
6169

70+
// functional component
71+
if (Ctor.options.functional) {
72+
return Ctor.options.render.call(
73+
null,
74+
parent.$createElement, // h
75+
propsData || {}, // props
76+
normalizeChildren(children) // children
77+
)
78+
}
79+
80+
// merge component management hooks onto the placeholder node
81+
mergeHooks(data)
82+
6283
// extract listeners, since these needs to be treated as
6384
// child component listeners instead of DOM listeners
6485
const listeners = data.on
@@ -71,9 +92,7 @@ export function createComponent (
7192
const vnode = new VNode(
7293
`vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
7394
data, undefined, undefined, undefined, undefined, context, host,
74-
{ Ctor, propsData, listeners, parent, tag, children: undefined }
75-
// children to be set later by renderElementWithChildren,
76-
// but before the init hook
95+
{ Ctor, propsData, listeners, parent, tag, children }
7796
)
7897
return vnode
7998
}

src/core/vdom/create-element.js

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

10-
export function renderElementWithChildren (
11-
vnode: VNode | void,
12-
children: VNodeChildren | void
13-
): VNode | Array<VNode> | void {
14-
if (vnode) {
15-
const componentOptions = vnode.componentOptions
16-
if (componentOptions) {
17-
if (process.env.NODE_ENV !== 'production' &&
18-
children && typeof children !== 'function') {
19-
warn(
20-
'A component\'s children should be a function that returns the ' +
21-
'children array. This allows the component to track the children ' +
22-
'dependencies and optimizes re-rendering.'
23-
)
24-
}
25-
const CtorOptions = componentOptions.Ctor.options
26-
// functional component
27-
if (CtorOptions.functional) {
28-
return CtorOptions.render.call(
29-
null,
30-
componentOptions.parent.$createElement, // h
31-
componentOptions.propsData || {}, // props
32-
normalizeChildren(children) // children
33-
)
34-
} else {
35-
// normal component
36-
componentOptions.children = children
37-
}
38-
} else {
39-
// normal element
40-
vnode.setChildren(normalizeChildren(children))
41-
}
42-
}
43-
return vnode
44-
}
45-
46-
export function renderElement (
10+
export function createElement (
4711
tag?: string | Class<Component> | Function | Object,
4812
data?: VNodeData,
13+
children?: VNodeChildren | void,
4914
namespace?: string
50-
): VNode | void {
15+
): VNode | Array<VNode> | void {
5116
// make sure to expose real self instead of proxy
5217
const context: Component = this._self
5318
const parent: ?Component = renderState.activeInstance
@@ -67,12 +32,12 @@ export function renderElement (
6732
let Ctor
6833
if (config.isReservedTag(tag)) {
6934
return new VNode(
70-
tag, data,
71-
undefined, undefined, undefined,
35+
tag, data, normalizeChildren(children),
36+
undefined, undefined,
7237
namespace, context, host
7338
)
7439
} else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
75-
return createComponent(Ctor, data, parent, context, host, tag)
40+
return createComponent(Ctor, data, parent, context, host, children, tag)
7641
} else {
7742
if (process.env.NODE_ENV !== 'production') {
7843
if (
@@ -88,20 +53,12 @@ export function renderElement (
8853
}
8954
}
9055
return new VNode(
91-
tag, data,
92-
undefined, undefined, undefined,
56+
tag, data, normalizeChildren(children),
57+
undefined, undefined,
9358
namespace, context, host
9459
)
9560
}
9661
} else {
97-
return createComponent(tag, data, parent, context, host)
62+
return createComponent(tag, data, parent, context, host, children)
9863
}
9964
}
100-
101-
export function renderStatic (index?: number): Object | void {
102-
return this._staticTrees[index] || (
103-
this._staticTrees[index] = this.$options.staticRenderFns[index].call(
104-
this._renderProxy
105-
)
106-
)
107-
}

src/core/vdom/helpers.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { isPrimitive } from '../util/index'
44
import VNode from './vnode'
55

6-
export function normalizeChildren (children: any): Array<VNode> {
6+
export function normalizeChildren (children: any): Array<VNode> | void {
77
// invoke children thunks.
88
// components always receive their children as thunks so that they
99
// can perform the actual render inside their own dependency collection cycle.
@@ -38,7 +38,6 @@ export function normalizeChildren (children: any): Array<VNode> {
3838
}
3939
return res
4040
}
41-
return []
4241
}
4342

4443
function createTextVNode (val) {

src/core/vdom/vnode.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class VNode {
1818
constructor (
1919
tag?: string,
2020
data?: VNodeData,
21-
children?: Array<VNode>,
21+
children?: Array<VNode> | void,
2222
text?: string,
2323
elm?: Node,
2424
ns?: string,
@@ -47,10 +47,6 @@ export default class VNode {
4747
constructHook(this)
4848
}
4949
}
50-
51-
setChildren (children?: Array<VNode>) {
52-
this.children = children
53-
}
5450
}
5551

5652
export const emptyVNode = () => new VNode(undefined, undefined, undefined, '')

src/platforms/web/compiler/modules/transition.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ function genData (el: ASTElement): string {
2626

2727
function transformCode (el: ASTElement, code: string): string {
2828
return el.transitionMode
29-
? `_h(_e('TransitionControl',{props:{mode:${
29+
? `_h('TransitionControl',{props:{mode:${
3030
el.transitionMode
31-
},child:${code}}}))`
31+
},child:${code}}})`
3232
: code
3333
}
3434

0 commit comments

Comments
 (0)