+72
-13
lines changedFilter options
+72
-13
lines changed Original file line number Diff line number Diff line change
@@ -104,6 +104,8 @@ declare interface Component {
104
104
_b: (data: any, value: any, asProp?: boolean) => VNodeData;
105
105
// check custom keyCode
106
106
_k: (eventKeyCode: number, key: string, builtInAlias: number | Array<number> | void) => boolean;
107
+
// resolve scoped slots
108
+
_u: (scopedSlots: Array<[string, Function]>) => { [key: string]: Function };
107
109
108
110
// allow dynamic method registration
109
111
[key: string]: any
Original file line number Diff line number Diff line change
@@ -273,17 +273,17 @@ function genInlineTemplate (el: ASTElement): ?string {
273
273
}
274
274
275
275
function genScopedSlots (slots: { [key: string]: ASTElement }): string {
276
-
return `scopedSlots:{${
276
+
return `scopedSlots:_u([${
277
277
Object.keys(slots).map(key => genScopedSlot(key, slots[key])).join(',')
278
-
}}`
278
+
}])`
279
279
}
280
280
281
281
function genScopedSlot (key: string, el: ASTElement) {
282
-
return `${key}:function(${String(el.attrsMap.scope)}){` +
282
+
return `[${key},function(${String(el.attrsMap.scope)}){` +
283
283
`return ${el.tag === 'template'
284
284
? genChildren(el) || 'void 0'
285
285
: genElement(el)
286
-
}}`
286
+
}}]`
287
287
}
288
288
289
289
function genChildren (el: ASTElement, checkSkip?: boolean): string | void {
Original file line number Diff line number Diff line change
@@ -176,7 +176,7 @@ export function parse (
176
176
processIfConditions(element, currentParent)
177
177
} else if (element.slotScope) { // scoped slot
178
178
currentParent.plain = false
179
-
const name = element.slotTarget || 'default'
179
+
const name = element.slotTarget || '"default"'
180
180
;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element
181
181
} else {
182
182
currentParent.children.push(element)
Original file line number Diff line number Diff line change
@@ -3,9 +3,9 @@
3
3
import Watcher from '../observer/watcher'
4
4
import { createEmptyVNode } from '../vdom/vnode'
5
5
import { observerState } from '../observer/index'
6
-
import { warn, validateProp, remove, noop } from '../util/index'
7
-
import { resolveSlots } from './render-helpers/resolve-slots'
8
6
import { updateComponentListeners } from './events'
7
+
import { resolveSlots } from './render-helpers/resolve-slots'
8
+
import { warn, validateProp, remove, noop, emptyObject } from '../util/index'
9
9
10
10
export let activeInstance: any = null
11
11
@@ -120,13 +120,23 @@ export function lifecycleMixin (Vue: Class<Component>) {
120
120
renderChildren: ?Array<VNode>
121
121
) {
122
122
const vm: Component = this
123
-
const hasChildren = !!(vm.$options._renderChildren || renderChildren)
123
+
124
+
// determine whether component has slot children
125
+
// we need to do this before overwriting $options._renderChildren
126
+
const hasChildren = !!(
127
+
renderChildren || // has new static slots
128
+
vm.$options._renderChildren || // has old static slots
129
+
parentVnode.data.scopedSlots || // has new scoped slots
130
+
vm.$scopedSlots !== emptyObject // has old scoped slots
131
+
)
132
+
124
133
vm.$options._parentVnode = parentVnode
125
134
vm.$vnode = parentVnode // update vm's placeholder node without re-render
126
135
if (vm._vnode) { // update child tree's parent
127
136
vm._vnode.parent = parentVnode
128
137
}
129
138
vm.$options._renderChildren = renderChildren
139
+
130
140
// update props
131
141
if (propsData && vm.$options.props) {
132
142
observerState.shouldConvert = false
Original file line number Diff line number Diff line change
@@ -38,3 +38,13 @@ export function resolveSlots (
38
38
}
39
39
return slots
40
40
}
41
+
42
+
export function resolveScopedSlots (
43
+
fns: Array<[string, Function]>
44
+
): { [key: string]: Function } {
45
+
const res = {}
46
+
for (let i = 0; i < fns.length; i++) {
47
+
res[fns[i][0]] = fns[i][1]
48
+
}
49
+
return res
50
+
}
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import {
8
8
toNumber,
9
9
_toString,
10
10
looseEqual,
11
+
emptyObject,
11
12
looseIndexOf,
12
13
formatComponentName
13
14
} from '../util/index'
@@ -21,11 +22,11 @@ import VNode, {
21
22
import { createElement } from '../vdom/create-element'
22
23
import { renderList } from './render-helpers/render-list'
23
24
import { renderSlot } from './render-helpers/render-slot'
24
-
import { resolveSlots } from './render-helpers/resolve-slots'
25
25
import { resolveFilter } from './render-helpers/resolve-filter'
26
26
import { checkKeyCodes } from './render-helpers/check-keycodes'
27
27
import { bindObjectProps } from './render-helpers/bind-object-props'
28
28
import { renderStatic, markOnce } from './render-helpers/render-static'
29
+
import { resolveSlots, resolveScopedSlots } from './render-helpers/resolve-slots'
29
30
30
31
export function initRender (vm: Component) {
31
32
vm.$vnode = null // the placeholder node in parent tree
@@ -34,7 +35,7 @@ export function initRender (vm: Component) {
34
35
const parentVnode = vm.$options._parentVnode
35
36
const renderContext = parentVnode && parentVnode.context
36
37
vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext)
37
-
vm.$scopedSlots = {}
38
+
vm.$scopedSlots = emptyObject
38
39
// bind the createElement fn to this instance
39
40
// so that we get proper render context inside it.
40
41
// args order: tag, data, children, normalizationType, alwaysNormalize
@@ -65,9 +66,7 @@ export function renderMixin (Vue: Class<Component>) {
65
66
}
66
67
}
67
68
68
-
if (_parentVnode && _parentVnode.data.scopedSlots) {
69
-
vm.$scopedSlots = _parentVnode.data.scopedSlots
70
-
}
69
+
vm.$scopedSlots = (_parentVnode && _parentVnode.data.scopedSlots) || emptyObject
71
70
72
71
if (staticRenderFns && !vm._staticTrees) {
73
72
vm._staticTrees = []
@@ -124,4 +123,5 @@ export function renderMixin (Vue: Class<Component>) {
124
123
Vue.prototype._b = bindObjectProps
125
124
Vue.prototype._v = createTextVNode
126
125
Vue.prototype._e = createEmptyVNode
126
+
Vue.prototype._u = resolveScopedSlots
127
127
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
1
1
/* @flow */
2
2
3
+
export const emptyObject = Object.freeze({})
4
+
3
5
/**
4
6
* Check if a string starts with $ or _
5
7
*/
Original file line number Diff line number Diff line change
@@ -325,6 +325,41 @@ describe('Component scoped slot', () => {
325
325
expect(vm.$el.innerHTML).toBe('<span>hello</span>')
326
326
})
327
327
328
+
// #4779
329
+
it('should support dynamic slot target', done => {
330
+
const Child = {
331
+
template: `
332
+
<div>
333
+
<slot name="a" msg="a" />
334
+
<slot name="b" msg="b" />
335
+
</div>
336
+
`
337
+
}
338
+
339
+
const vm = new Vue({
340
+
data: {
341
+
a: 'a',
342
+
b: 'b'
343
+
},
344
+
template: `
345
+
<child>
346
+
<template :slot="a" scope="props">A {{ props.msg }}</template>
347
+
<template :slot="b" scope="props">B {{ props.msg }}</template>
348
+
</child>
349
+
`,
350
+
components: { Child }
351
+
}).$mount()
352
+
353
+
expect(vm.$el.textContent.trim()).toBe('A a B b')
354
+
355
+
// switch slots
356
+
vm.a = 'b'
357
+
vm.b = 'a'
358
+
waitForUpdate(() => {
359
+
expect(vm.$el.textContent.trim()).toBe('B a A b')
360
+
}).then(done)
361
+
})
362
+
328
363
it('render function usage (JSX)', () => {
329
364
const vm = new Vue({
330
365
render (h) {
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4