forked from vuejs/vue-test-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate-scoped-slots.js
78 lines (70 loc) · 1.93 KB
/
create-scoped-slots.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// @flow
import Vue from 'vue'
import { compileToFunctions } from 'vue-template-compiler'
import { throwError, vueVersion } from 'shared/util'
function isDestructuringSlotScope (slotScope: string): boolean {
return slotScope[0] === '{' && slotScope[slotScope.length - 1] === '}'
}
function getVueTemplateCompilerHelpers (): { [name: string]: Function } {
const vue = new Vue()
const helpers = {}
const names = [
'_c',
'_o',
'_n',
'_s',
'_l',
'_t',
'_q',
'_i',
'_m',
'_f',
'_k',
'_b',
'_v',
'_e',
'_u',
'_g'
]
names.forEach(name => {
helpers[name] = vue._renderProxy[name]
})
helpers.$createElement = vue._renderProxy.$createElement
return helpers
}
function validateEnvironment (): void {
if (vueVersion < 2.1) {
throwError(`the scopedSlots option is only supported in ` + `[email protected]+.`)
}
}
const scopedSlotRe = /<[^>]+ slot-scope=\"(.+)\"/
export default function createScopedSlots (
scopedSlotsOption: ?{ [slotName: string]: string | Function }
): { [slotName: string]: (props: Object) => VNode | Array<VNode>} {
const scopedSlots = {}
if (!scopedSlotsOption) {
return scopedSlots
}
validateEnvironment()
const helpers = getVueTemplateCompilerHelpers()
for (const s in scopedSlotsOption) {
const slot = scopedSlotsOption[s]
const isFn = typeof slot === 'function'
const renderFn = isFn
? slot
: compileToFunctions(slot).renderFn
const hasSlotScopeAttr = !isFn && slot.match(scopedSlotRe)
// // $FlowIgnore
const slotScope = hasSlotScopeAttr && hasSlotScopeAttr[1]
scopedSlots[s] = function (props) {
if (isFn) {
return renderFn.call({ ...helpers }, props)
} else if (slotScope && !isDestructuringSlotScope(slotScope)) {
return renderFn.call({ ...helpers, [slotScope]: props })
} else {
return renderFn.call({ ...helpers, ...props })
}
}
}
return scopedSlots
}