Skip to content

Commit ce457f9

Browse files
posvazrh122
andauthored
fix(slot): add a function to return the slot fallback content (vuejs#12014)
Co-authored-by: zrh122 <1229550935@qq.com>
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 12 additions & 8 deletions
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

Lines changed: 41 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy