Skip to content

Commit b1e66b4

Browse files
committed
refactor: split render helpers into separate files
1 parent 92c2cce commit b1e66b4

10 files changed

+263
-213
lines changed

src/core/instance/lifecycle.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Watcher from '../observer/watcher'
44
import { createEmptyVNode } from '../vdom/vnode'
55
import { observerState } from '../observer/index'
66
import { warn, validateProp, remove, noop } from '../util/index'
7-
import { resolveSlots } from './render'
7+
import { resolveSlots } from './render-helpers/resolve-slots'
88
import { updateComponentListeners } from './events'
99

1010
export let activeInstance: any = null
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* @flow */
2+
3+
import config from 'core/config'
4+
import { isObject, warn, toObject } from 'core/util/index'
5+
6+
/**
7+
* Runtime helper for merging v-bind="object" into a VNode's data.
8+
*/
9+
export function bindObjectProps (
10+
data: any,
11+
tag: string,
12+
value: any,
13+
asProp?: boolean
14+
): VNodeData {
15+
if (value) {
16+
if (!isObject(value)) {
17+
process.env.NODE_ENV !== 'production' && warn(
18+
'v-bind without argument expects an Object or Array value',
19+
this
20+
)
21+
} else {
22+
if (Array.isArray(value)) {
23+
value = toObject(value)
24+
}
25+
for (const key in value) {
26+
if (key === 'class' || key === 'style') {
27+
data[key] = value[key]
28+
} else {
29+
const type = data.attrs && data.attrs.type
30+
const hash = asProp || config.mustUseProp(tag, type, key)
31+
? data.domProps || (data.domProps = {})
32+
: data.attrs || (data.attrs = {})
33+
hash[key] = value[key]
34+
}
35+
}
36+
}
37+
}
38+
return data
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* @flow */
2+
3+
import config from 'core/config'
4+
5+
/**
6+
* Runtime helper for checking keyCodes from config.
7+
*/
8+
export function checkKeyCodes (
9+
eventKeyCode: number,
10+
key: string,
11+
builtInAlias: number | Array<number> | void
12+
): boolean {
13+
const keyCodes = config.keyCodes[key] || builtInAlias
14+
if (Array.isArray(keyCodes)) {
15+
return keyCodes.indexOf(eventKeyCode) === -1
16+
} else {
17+
return keyCodes !== eventKeyCode
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* @flow */
2+
3+
import { isObject } from 'core/util/index'
4+
5+
/**
6+
* Runtime helper for rendering v-for lists.
7+
*/
8+
export function renderList (
9+
val: any,
10+
render: () => VNode
11+
): ?Array<VNode> {
12+
let ret: ?Array<VNode>, i, l, keys, key
13+
if (Array.isArray(val) || typeof val === 'string') {
14+
ret = new Array(val.length)
15+
for (i = 0, l = val.length; i < l; i++) {
16+
ret[i] = render(val[i], i)
17+
}
18+
} else if (typeof val === 'number') {
19+
ret = new Array(val)
20+
for (i = 0; i < val; i++) {
21+
ret[i] = render(i + 1, i)
22+
}
23+
} else if (isObject(val)) {
24+
keys = Object.keys(val)
25+
ret = new Array(keys.length)
26+
for (i = 0, l = keys.length; i < l; i++) {
27+
key = keys[i]
28+
ret[i] = render(val[key], key, i)
29+
}
30+
}
31+
return ret
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* @flow */
2+
3+
import { extend, warn } from 'core/util/index'
4+
5+
/**
6+
* Runtime helper for rendering <slot>
7+
*/
8+
export function renderSlot (
9+
name: string,
10+
fallback: ?Array<VNode>,
11+
props: ?Object,
12+
bindObject: ?Object
13+
): ?Array<VNode> {
14+
const scopedSlotFn = this.$scopedSlots[name]
15+
if (scopedSlotFn) { // scoped slot
16+
props = props || {}
17+
if (bindObject) {
18+
extend(props, bindObject)
19+
}
20+
return scopedSlotFn(props) || fallback
21+
} else {
22+
const slotNodes = this.$slots[name]
23+
// warn duplicate slot usage
24+
if (slotNodes && process.env.NODE_ENV !== 'production') {
25+
slotNodes._rendered && warn(
26+
`Duplicate presence of slot "${name}" found in the same render tree ` +
27+
`- this will likely cause render errors.`,
28+
this
29+
)
30+
slotNodes._rendered = true
31+
}
32+
return slotNodes || fallback
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* @flow */
2+
3+
import { cloneVNode, cloneVNodes } from 'core/vdom/vnode'
4+
5+
/**
6+
* Runtime helper for rendering static trees.
7+
*/
8+
export function renderStatic (
9+
index: number,
10+
isInFor?: boolean
11+
): VNode | Array<VNode> {
12+
let tree = this._staticTrees[index]
13+
// if has already-rendered static tree and not inside v-for,
14+
// we can reuse the same tree by doing a shallow clone.
15+
if (tree && !isInFor) {
16+
return Array.isArray(tree)
17+
? cloneVNodes(tree)
18+
: cloneVNode(tree)
19+
}
20+
// otherwise, render a fresh tree.
21+
tree = this._staticTrees[index] =
22+
this.$options.staticRenderFns[index].call(this._renderProxy)
23+
markStatic(tree, `__static__${index}`, false)
24+
return tree
25+
}
26+
27+
/**
28+
* Runtime helper for v-once.
29+
* Effectively it means marking the node as static with a unique key.
30+
*/
31+
export function markOnce (
32+
tree: VNode | Array<VNode>,
33+
index: number,
34+
key: string
35+
) {
36+
markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true)
37+
return tree
38+
}
39+
40+
function markStatic (
41+
tree: VNode | Array<VNode>,
42+
key: string,
43+
isOnce: boolean
44+
) {
45+
if (Array.isArray(tree)) {
46+
for (let i = 0; i < tree.length; i++) {
47+
if (tree[i] && typeof tree[i] !== 'string') {
48+
markStaticNode(tree[i], `${key}_${i}`, isOnce)
49+
}
50+
}
51+
} else {
52+
markStaticNode(tree, key, isOnce)
53+
}
54+
}
55+
56+
function markStaticNode (node, key, isOnce) {
57+
node.isStatic = true
58+
node.key = key
59+
node.isOnce = isOnce
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* @flow */
2+
3+
import { identity, resolveAsset } from 'core/util/index'
4+
5+
/**
6+
* Runtime helper for resolving filters
7+
*/
8+
export function resolveFilter (id: string): Function {
9+
return resolveAsset(this.$options, 'filters', id, true) || identity
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* @flow */
2+
3+
/**
4+
* Runtime helper for resolving raw children VNodes into a slot object.
5+
*/
6+
export function resolveSlots (
7+
children: ?Array<VNode>,
8+
context: ?Component
9+
): { [key: string]: Array<VNode> } {
10+
const slots = {}
11+
if (!children) {
12+
return slots
13+
}
14+
const defaultSlot = []
15+
let name, child
16+
for (let i = 0, l = children.length; i < l; i++) {
17+
child = children[i]
18+
// named slots should only be respected if the vnode was rendered in the
19+
// same context.
20+
if ((child.context === context || child.functionalContext === context) &&
21+
child.data && (name = child.data.slot)) {
22+
const slot = (slots[name] || (slots[name] = []))
23+
if (child.tag === 'template') {
24+
slot.push.apply(slot, child.children)
25+
} else {
26+
slot.push(child)
27+
}
28+
} else {
29+
defaultSlot.push(child)
30+
}
31+
}
32+
// ignore single whitespace
33+
if (defaultSlot.length && !(
34+
defaultSlot.length === 1 &&
35+
(defaultSlot[0].text === ' ' || defaultSlot[0].isComment)
36+
)) {
37+
slots.default = defaultSlot
38+
}
39+
return slots
40+
}

0 commit comments

Comments
 (0)