Skip to content

Commit ce457f9

Browse files
posvazrh122
andauthored
fix(slot): add a function to return the slot fallback content (#12014)
Co-authored-by: zrh122 <[email protected]>
1 parent 77b5330 commit ce457f9

File tree

4 files changed

+55
-10
lines changed

4 files changed

+55
-10
lines changed

src/compiler/codegen/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ export function genComment (comment: ASTText): string {
547547
function genSlot (el: ASTElement, state: CodegenState): string {
548548
const slotName = el.slotName || '"default"'
549549
const children = genChildren(el, state)
550-
let res = `_t(${slotName}${children ? `,${children}` : ''}`
550+
let res = `_t(${slotName}${children ? `,function(){return ${children}}` : ''}`
551551
const attrs = el.attrs || el.dynamicAttrs
552552
? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
553553
// slot props are camelized

src/core/instance/render-helpers/render-slot.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,30 @@ import { extend, warn, isObject } from 'core/util/index'
77
*/
88
export function renderSlot (
99
name: string,
10-
fallback: ?Array<VNode>,
10+
fallbackRender: ?((() => Array<VNode>) | Array<VNode>),
1111
props: ?Object,
1212
bindObject: ?Object
1313
): ?Array<VNode> {
1414
const scopedSlotFn = this.$scopedSlots[name]
1515
let nodes
16-
if (scopedSlotFn) { // scoped slot
16+
if (scopedSlotFn) {
17+
// scoped slot
1718
props = props || {}
1819
if (bindObject) {
1920
if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) {
20-
warn(
21-
'slot v-bind without argument expects an Object',
22-
this
23-
)
21+
warn('slot v-bind without argument expects an Object', this)
2422
}
2523
props = extend(extend({}, bindObject), props)
2624
}
27-
nodes = scopedSlotFn(props) || fallback
25+
nodes =
26+
scopedSlotFn(props) ||
27+
(fallbackRender &&
28+
(Array.isArray(fallbackRender) ? fallbackRender : fallbackRender()))
2829
} else {
29-
nodes = this.$slots[name] || fallback
30+
nodes =
31+
this.$slots[name] ||
32+
(fallbackRender &&
33+
(Array.isArray(fallbackRender) ? fallbackRender : fallbackRender()))
3034
}
3135

3236
const target = props && props.slot

test/unit/features/component/component-slot.spec.js

+41
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,47 @@ describe('Component slot', () => {
109109
expect(child.$el.children[1].textContent).toBe('slot b')
110110
})
111111

112+
it('it should work with previous versions of the templates', () => {
113+
const Test = {
114+
render() {
115+
var _vm = this;
116+
var _h = _vm.$createElement;
117+
var _c = _vm._self._c || vm._h;
118+
return _c('div', [_vm._t("default", [_c('p', [_vm._v("slot default")])])], 2)
119+
}
120+
}
121+
let vm = new Vue({
122+
template: `<test/>`,
123+
components: { Test }
124+
}).$mount()
125+
expect(vm.$el.textContent).toBe('slot default')
126+
vm = new Vue({
127+
template: `<test>custom content</test>`,
128+
components: { Test }
129+
}).$mount()
130+
expect(vm.$el.textContent).toBe('custom content')
131+
})
132+
133+
it('fallback content should not be evaluated when the parent is providing it', () => {
134+
const test = jasmine.createSpy('test')
135+
const vm = new Vue({
136+
template: '<test>slot default</test>',
137+
components: {
138+
test: {
139+
template: '<div><slot>{{test()}}</slot></div>',
140+
methods: {
141+
test () {
142+
test()
143+
return 'test'
144+
}
145+
}
146+
}
147+
}
148+
}).$mount()
149+
expect(vm.$el.textContent).toBe('slot default')
150+
expect(test).not.toHaveBeenCalled()
151+
})
152+
112153
it('selector matching multiple elements', () => {
113154
mount({
114155
childTemplate: '<div><slot name="t"></slot></div>',

test/unit/modules/compiler/codegen.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ describe('codegen', () => {
196196
it('generate slot fallback content', () => {
197197
assertCodegen(
198198
'<div><slot><div>hi</div></slot></div>',
199-
`with(this){return _c('div',[_t("default",[_c('div',[_v("hi")])])],2)}`
199+
`with(this){return _c('div',[_t("default",function(){return [_c('div',[_v("hi")])]})],2)}`
200200
)
201201
})
202202

0 commit comments

Comments
 (0)