Skip to content

Commit 6b73d4b

Browse files
authored
fix: make scoped slots rendering consistent for stubs (#2068)
Co-authored-by: Illya <[email protected]>
1 parent 0d4543d commit 6b73d4b

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

Diff for: packages/create-instance/create-component-stubs.js

+11-13
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,8 @@ function getScopedSlotRenderFunctions(ctx: any): Array<string> {
7777
// In Vue 2.6+ a new v-slot syntax was introduced
7878
// scopedSlots are now saved in parent._vnode.data.scopedSlots
7979
// We filter out _normalized, $stable and $key keys
80-
if (
81-
ctx &&
82-
ctx.$options &&
83-
ctx.$options.parent &&
84-
ctx.$options.parent._vnode &&
85-
ctx.$options.parent._vnode.data &&
86-
ctx.$options.parent._vnode.data.scopedSlots
87-
) {
88-
const slotKeys: Array<string> = ctx.$options.parent._vnode.data.scopedSlots
89-
return keys(slotKeys).filter(
80+
if (ctx.$vnode.data.scopedSlots) {
81+
return keys(ctx.$vnode.data.scopedSlots).filter(
9082
x => x !== '_normalized' && x !== '$stable' && x !== '$key'
9183
)
9284
}
@@ -130,9 +122,15 @@ export function createStubFromComponent(
130122
context
131123
? context.children
132124
: this.$options._renderChildren ||
133-
getScopedSlotRenderFunctions(this).map(x =>
134-
this.$options.parent._vnode.data.scopedSlots[x]({})
135-
)
125+
getScopedSlotRenderFunctions(this)
126+
.map(x => {
127+
let result = null
128+
try {
129+
result = this.$vnode.data.scopedSlots[x]({})
130+
} catch (e) {}
131+
return result
132+
})
133+
.filter(Boolean)
136134
)
137135
}
138136
}

Diff for: test/specs/shallow-mount.spec.js

+32
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,38 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => {
164164
)
165165
})
166166

167+
it('renders named slots with v-slot syntax when they are wrapped', () => {
168+
const localVue = createLocalVue()
169+
localVue.component('Foo', {
170+
template: '<div><slot name="newSyntax" /></div>'
171+
})
172+
const TestComponent = {
173+
template: `
174+
<div>
175+
<Foo>
176+
<template v-slot:newSyntax>
177+
<p class="new-example">text</p>
178+
</template>
179+
</Foo>
180+
</div>
181+
`
182+
}
183+
const wrapper = shallowMount(TestComponent, {
184+
localVue
185+
})
186+
expect(wrapper.find({ name: 'Foo' }).exists()).toEqual(true)
187+
expect(wrapper.find('.new-example').exists()).toEqual(true)
188+
expect(wrapper.html()).toEqual(
189+
[
190+
'<div>',
191+
' <foo-stub>',
192+
' <p class="new-example">text</p>',
193+
' </foo-stub>',
194+
'</div>'
195+
].join('\n')
196+
)
197+
})
198+
167199
it('renders named slots when they are located inside component with v-if', () => {
168200
const localVue = createLocalVue()
169201
localVue.component('Foo', {

0 commit comments

Comments
 (0)