1 |
|
2 |
|
3 | import { def } from 'core/util/lang'
|
4 | import { normalizeChildren } from 'core/vdom/helpers/normalize-children'
|
5 | import { emptyObject } from 'shared/util'
|
6 |
|
7 | export function normalizeScopedSlots (
|
8 | slots: { [key: string]: Function } | void,
|
9 | normalSlots: { [key: string]: Array<VNode> },
|
10 | prevSlots?: { [key: string]: Function } | void
|
11 | ): any {
|
12 | let res
|
13 | const isStable = slots ? !!slots.$stable : true
|
14 | const key = slots && slots.$key
|
15 | if (!slots) {
|
16 | res = {}
|
17 | } else if (slots._normalized) {
|
18 |
|
19 | return slots._normalized
|
20 | } else if (
|
21 | isStable &&
|
22 | prevSlots &&
|
23 | prevSlots !== emptyObject &&
|
24 | key === prevSlots.$key &&
|
25 | Object.keys(normalSlots).length === 0
|
26 | ) {
|
27 |
|
28 |
|
29 | return prevSlots
|
30 | } else {
|
31 | res = {}
|
32 | for (const key in slots) {
|
33 | if (slots[key] && key[0] !== '$') {
|
34 | res[key] = normalizeScopedSlot(normalSlots, key, slots[key])
|
35 | }
|
36 | }
|
37 | }
|
38 |
|
39 | for (const key in normalSlots) {
|
40 | if (!(key in res)) {
|
41 | res[key] = proxyNormalSlot(normalSlots, key)
|
42 | }
|
43 | }
|
44 |
|
45 |
|
46 | if (slots && Object.isExtensible(slots)) {
|
47 | (slots: any)._normalized = res
|
48 | }
|
49 | def(res, '$stable', isStable)
|
50 | def(res, '$key', key)
|
51 | return res
|
52 | }
|
53 |
|
54 | function normalizeScopedSlot(normalSlots, key, fn) {
|
55 | const normalized = function () {
|
56 | let res = arguments.length ? fn.apply(null, arguments) : fn({})
|
57 | res = res && typeof res === 'object' && !Array.isArray(res)
|
58 | ? [res]
|
59 | : normalizeChildren(res)
|
60 | return res && res.length === 0
|
61 | ? undefined
|
62 | : res
|
63 | }
|
64 |
|
65 |
|
66 |
|
67 | if (fn.proxy) {
|
68 | Object.defineProperty(normalSlots, key, {
|
69 | get: normalized,
|
70 | enumerable: true,
|
71 | configurable: true
|
72 | })
|
73 | }
|
74 | return normalized
|
75 | }
|
76 |
|
77 | function proxyNormalSlot(slots, key) {
|
78 | return () => slots[key]
|
79 | }
|