Skip to content

Commit 0eb8cdc

Browse files
committed
support v-bind object on scoped slots (fix #4529)
1 parent bc140de commit 0eb8cdc

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

Diff for: src/compiler/codegen/index.js

+13-7
Original file line numberDiff line numberDiff line change
@@ -343,13 +343,19 @@ function genText (text: ASTText | ASTExpression): string {
343343
function genSlot (el: ASTElement): string {
344344
const slotName = el.slotName || '"default"'
345345
const children = genChildren(el)
346-
return `_t(${slotName}${
347-
children ? `,${children}` : ''
348-
}${
349-
el.attrs ? `${children ? '' : ',null'},{${
350-
el.attrs.map(a => `${camelize(a.name)}:${a.value}`).join(',')
351-
}}` : ''
352-
})`
346+
let res = `_t(${slotName}${children ? `,${children}` : ''}`
347+
const attrs = el.attrs && `{${el.attrs.map(a => `${camelize(a.name)}:${a.value}`).join(',')}}`
348+
const bind = el.attrsMap['v-bind']
349+
if ((attrs || bind) && !children) {
350+
res += `,null`
351+
}
352+
if (attrs) {
353+
res += `,${attrs}`
354+
}
355+
if (bind) {
356+
res += `${attrs ? '' : ',null'},${bind}`
357+
}
358+
return res + ')'
353359
}
354360

355361
// componentName is el.component, take it as argument to shun flow's pessimistic refinement

Diff for: src/core/instance/render.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import VNode, {
99
} from '../vdom/vnode'
1010
import {
1111
warn,
12+
extend,
1213
identity,
1314
isObject,
1415
toObject,
@@ -203,11 +204,16 @@ export function renderMixin (Vue: Class<Component>) {
203204
Vue.prototype._t = function (
204205
name: string,
205206
fallback: ?Array<VNode>,
206-
props: ?Object
207+
props: ?Object,
208+
bindObject: ?Object
207209
): ?Array<VNode> {
208210
const scopedSlotFn = this.$scopedSlots[name]
209211
if (scopedSlotFn) { // scoped slot
210-
return scopedSlotFn(props || {}) || fallback
212+
props = props || {}
213+
if (bindObject) {
214+
extend(props, bindObject)
215+
}
216+
return scopedSlotFn(props) || fallback
211217
} else {
212218
const slotNodes = this.$slots[name]
213219
// warn duplicate slot usage

Diff for: test/unit/features/component/component-scoped-slot.spec.js

+34
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,40 @@ describe('Component scoped slot', () => {
3131
}).then(done)
3232
})
3333

34+
it('with v-bind', done => {
35+
const vm = new Vue({
36+
template: `
37+
<test ref="test">
38+
<template scope="props">
39+
<span>{{ props.msg }} {{ props.msg2 }}</span>
40+
</template>
41+
</test>
42+
`,
43+
components: {
44+
test: {
45+
data () {
46+
return {
47+
msg: 'hello',
48+
obj: { msg2: 'world' }
49+
}
50+
},
51+
template: `
52+
<div>
53+
<slot :msg="msg" v-bind="obj"></slot>
54+
</div>
55+
`
56+
}
57+
}
58+
}).$mount()
59+
60+
expect(vm.$el.innerHTML).toBe('<span>hello world</span>')
61+
vm.$refs.test.msg = 'bye'
62+
vm.$refs.test.obj.msg2 = 'bye'
63+
waitForUpdate(() => {
64+
expect(vm.$el.innerHTML).toBe('<span>bye bye</span>')
65+
}).then(done)
66+
})
67+
3468
it('template slot', done => {
3569
const vm = new Vue({
3670
template: `

0 commit comments

Comments
 (0)