Skip to content

Commit d3aee4e

Browse files
committed
make vdom hot code more explicit and vm friendly
1 parent 86a714c commit d3aee4e

File tree

4 files changed

+54
-32
lines changed

4 files changed

+54
-32
lines changed

Diff for: src/core/vdom/create-component.js

+17-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { resolveSlots } from '../instance/render-helpers/resolve-slots'
77

88
import {
99
warn,
10+
isDef,
11+
isUndef,
12+
isTrue,
1013
isObject,
1114
validateProp
1215
} from '../util/index'
@@ -83,21 +86,25 @@ const componentVNodeHooks = {
8386
const hooksToMerge = Object.keys(componentVNodeHooks)
8487

8588
export function createComponent (
86-
Ctor: Class<Component> | Function | Object | void,
89+
Ctor: any,
8790
data?: VNodeData,
8891
context: Component,
8992
children: ?Array<VNode>,
9093
tag?: string
9194
): VNode | void {
92-
if (!Ctor) {
95+
if (isUndef(Ctor)) {
9396
return
9497
}
9598

9699
const baseCtor = context.$options._base
100+
101+
// plain options object: turn it into a constructor
97102
if (isObject(Ctor)) {
98103
Ctor = baseCtor.extend(Ctor)
99104
}
100105

106+
// if at this stage it's not a constructor or an async component factory,
107+
// reject.
101108
if (typeof Ctor !== 'function') {
102109
if (process.env.NODE_ENV !== 'production') {
103110
warn(`Invalid Component definition: ${String(Ctor)}`, context)
@@ -106,8 +113,8 @@ export function createComponent (
106113
}
107114

108115
// async component
109-
if (!Ctor.cid) {
110-
if (Ctor.resolved) {
116+
if (isUndef(Ctor.cid)) {
117+
if (isDef(Ctor.resolved)) {
111118
Ctor = Ctor.resolved
112119
} else {
113120
Ctor = resolveAsyncComponent(Ctor, baseCtor, () => {
@@ -130,15 +137,15 @@ export function createComponent (
130137
data = data || {}
131138

132139
// transform component v-model data into props & events
133-
if (data.model) {
140+
if (isDef(data.model)) {
134141
transformModel(Ctor.options, data)
135142
}
136143

137144
// extract props
138145
const propsData = extractPropsFromVNodeData(data, Ctor, tag)
139146

140147
// functional component
141-
if (Ctor.options.functional) {
148+
if (isTrue(Ctor.options.functional)) {
142149
return createFunctionalComponent(Ctor, propsData, data, context, children)
143150
}
144151

@@ -148,7 +155,7 @@ export function createComponent (
148155
// replace with listeners with .native modifier
149156
data.on = data.nativeOn
150157

151-
if (Ctor.options.abstract) {
158+
if (isTrue(Ctor.options.abstract)) {
152159
// abstract components do not keep anything
153160
// other than props & listeners
154161
data = {}
@@ -176,7 +183,7 @@ function createFunctionalComponent (
176183
): VNode | void {
177184
const props = {}
178185
const propOptions = Ctor.options.props
179-
if (propOptions) {
186+
if (isDef(propOptions)) {
180187
for (const key in propOptions) {
181188
props[key] = validateProp(key, propOptions, propsData)
182189
}
@@ -221,7 +228,7 @@ export function createComponentInstanceForVnode (
221228
}
222229
// check inline-template render functions
223230
const inlineTemplate = vnode.data.inlineTemplate
224-
if (inlineTemplate) {
231+
if (isDef(inlineTemplate)) {
225232
options.render = inlineTemplate.render
226233
options.staticRenderFns = inlineTemplate.staticRenderFns
227234
}
@@ -254,7 +261,7 @@ function transformModel (options, data: any) {
254261
const event = (options.model && options.model.event) || 'input'
255262
;(data.props || (data.props = {}))[prop] = data.model.value
256263
const on = data.on || (data.on = {})
257-
if (on[event]) {
264+
if (isDef(on[event])) {
258265
on[event] = [data.model.callback].concat(on[event])
259266
} else {
260267
on[event] = data.model.callback

Diff for: src/core/vdom/create-element.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import { createComponent } from './create-component'
66

77
import {
88
warn,
9-
resolveAsset,
10-
isPrimitive
9+
isDef,
10+
isUndef,
11+
isTrue,
12+
isPrimitive,
13+
resolveAsset
1114
} from '../util/index'
1215

1316
import {
@@ -33,7 +36,9 @@ export function createElement (
3336
children = data
3437
data = undefined
3538
}
36-
if (alwaysNormalize) normalizationType = ALWAYS_NORMALIZE
39+
if (isTrue(alwaysNormalize)) {
40+
normalizationType = ALWAYS_NORMALIZE
41+
}
3742
return _createElement(context, tag, data, children, normalizationType)
3843
}
3944

@@ -44,7 +49,7 @@ export function _createElement (
4449
children?: any,
4550
normalizationType?: number
4651
): VNode {
47-
if (data && data.__ob__) {
52+
if (isDef(data) && isDef((data: any).__ob__)) {
4853
process.env.NODE_ENV !== 'production' && warn(
4954
`Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
5055
'Always create fresh vnode data objects in each render!',
@@ -78,7 +83,7 @@ export function _createElement (
7883
config.parsePlatformTagName(tag), data, children,
7984
undefined, undefined, context
8085
)
81-
} else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
86+
} else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
8287
// component
8388
vnode = createComponent(Ctor, data, context, children, tag)
8489
} else {
@@ -94,7 +99,7 @@ export function _createElement (
9499
// direct component options / constructor
95100
vnode = createComponent(tag, data, context, children)
96101
}
97-
if (vnode) {
102+
if (vnode !== undefined) {
98103
if (ns) applyNS(vnode, ns)
99104
return vnode
100105
} else {
@@ -108,10 +113,10 @@ function applyNS (vnode, ns) {
108113
// use default namespace inside foreignObject
109114
return
110115
}
111-
if (vnode.children) {
116+
if (Array.isArray(vnode.children)) {
112117
for (let i = 0, l = vnode.children.length; i < l; i++) {
113118
const child = vnode.children[i]
114-
if (child.tag && !child.ns) {
119+
if (isDef(child.tag) && isUndef(child.ns)) {
115120
applyNS(child, ns)
116121
}
117122
}

Diff for: src/core/vdom/patch.js

+10-14
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,22 @@
1515
import VNode from './vnode'
1616
import config from '../config'
1717
import { SSR_ATTR } from 'shared/util'
18-
import { makeMap, isPrimitive, warn } from '../util/index'
19-
import { activeInstance } from '../instance/lifecycle'
2018
import { registerRef } from './modules/ref'
19+
import { activeInstance } from '../instance/lifecycle'
20+
21+
import {
22+
warn,
23+
isDef,
24+
isUndef,
25+
isTrue,
26+
makeMap,
27+
isPrimitive
28+
} from '../util/index'
2129

2230
export const emptyNode = new VNode('', {}, [])
2331

2432
const hooks = ['create', 'activate', 'update', 'remove', 'destroy']
2533

26-
function isUndef (v) {
27-
return v === undefined || v === null
28-
}
29-
30-
function isDef (v) {
31-
return v !== undefined && v !== null
32-
}
33-
34-
function isTrue (v) {
35-
return v === true
36-
}
37-
3834
function sameVnode (a, b) {
3935
return (
4036
a.key === b.key &&

Diff for: src/shared/util.js

+14
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
export const SSR_ATTR = 'data-server-rendered'
44

5+
// these helpers produces better vm code in JS engines due to their
6+
// explicitness and function inlining
7+
export function isUndef (v: any): boolean {
8+
return v === undefined || v === null
9+
}
10+
11+
export function isDef (v: any): boolean {
12+
return v !== undefined && v !== null
13+
}
14+
15+
export function isTrue (v: any): boolean {
16+
return v === true
17+
}
18+
519
/**
620
* Convert a value to a string that is actually rendered.
721
*/

0 commit comments

Comments
 (0)