fix(runtime-core): force diff slot fallback content and provided content
fix #7256 fix #9200 fix #9308 close #7266 close #9213
This commit is contained in:
parent
685e3f381c
commit
d76dd9c58d
|
@ -26,13 +26,17 @@ describe('renderSlot', () => {
|
|||
const vnode = renderSlot(
|
||||
{ default: () => [(child = h('child'))] },
|
||||
'default',
|
||||
{ key: 'foo' },
|
||||
)
|
||||
expect(vnode.children).toEqual([child])
|
||||
expect(vnode.key).toBe('foo')
|
||||
})
|
||||
|
||||
it('should render slot fallback', () => {
|
||||
const vnode = renderSlot({}, 'default', {}, () => ['fallback'])
|
||||
const vnode = renderSlot({}, 'default', { key: 'foo' }, () => ['fallback'])
|
||||
expect(vnode.children).toEqual(['fallback'])
|
||||
// should attach fallback key postfix
|
||||
expect(vnode.key).toBe('foo_fb')
|
||||
})
|
||||
|
||||
it('should warn render ssr slot', () => {
|
||||
|
|
|
@ -1105,4 +1105,77 @@ describe('renderer: optimized mode', () => {
|
|||
expect(app.config.errorHandler).not.toHaveBeenCalled()
|
||||
}
|
||||
})
|
||||
|
||||
test('diff slot and slot fallback node', async () => {
|
||||
const Comp = {
|
||||
props: ['show'],
|
||||
setup(props: any, { slots }: SetupContext) {
|
||||
return () => {
|
||||
return (
|
||||
openBlock(),
|
||||
createElementBlock('div', null, [
|
||||
renderSlot(slots, 'default', { hide: !props.show }, () => [
|
||||
(openBlock(),
|
||||
(block = createElementBlock(
|
||||
Fragment,
|
||||
{ key: 0 },
|
||||
[createTextVNode('foo')],
|
||||
PatchFlags.STABLE_FRAGMENT,
|
||||
))),
|
||||
]),
|
||||
])
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const show = ref(true)
|
||||
const app = createApp({
|
||||
render() {
|
||||
return (
|
||||
openBlock(),
|
||||
createBlock(
|
||||
Comp,
|
||||
{ show: show.value },
|
||||
{
|
||||
default: withCtx(({ hide }: { hide: boolean }) => [
|
||||
!hide
|
||||
? (openBlock(),
|
||||
createElementBlock(
|
||||
Fragment,
|
||||
{ key: 0 },
|
||||
[
|
||||
createCommentVNode('comment'),
|
||||
createElementVNode(
|
||||
'div',
|
||||
null,
|
||||
'bar',
|
||||
PatchFlags.HOISTED,
|
||||
),
|
||||
],
|
||||
PatchFlags.STABLE_FRAGMENT,
|
||||
))
|
||||
: createCommentVNode('v-if', true),
|
||||
]),
|
||||
_: SlotFlags.STABLE,
|
||||
},
|
||||
PatchFlags.PROPS,
|
||||
['show'],
|
||||
)
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
app.mount(root)
|
||||
expect(inner(root)).toBe('<div><!--comment--><div>bar</div></div>')
|
||||
expect(block).toBe(null)
|
||||
|
||||
show.value = false
|
||||
await nextTick()
|
||||
expect(inner(root)).toBe('<div>foo</div>')
|
||||
|
||||
show.value = true
|
||||
await nextTick()
|
||||
expect(inner(root)).toBe('<div><!--comment--><div>bar</div></div>')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -65,11 +65,13 @@ export function renderSlot(
|
|||
Fragment,
|
||||
{
|
||||
key:
|
||||
props.key ||
|
||||
// slot content array of a dynamic conditional slot may have a branch
|
||||
// key attached in the `createSlots` helper, respect that
|
||||
(validSlotContent && (validSlotContent as any).key) ||
|
||||
`_${name}`,
|
||||
(props.key ||
|
||||
// slot content array of a dynamic conditional slot may have a branch
|
||||
// key attached in the `createSlots` helper, respect that
|
||||
(validSlotContent && (validSlotContent as any).key) ||
|
||||
`_${name}`) +
|
||||
// #7256 force differentiate fallback content from actual content
|
||||
(!validSlotContent && fallback ? '_fb' : ''),
|
||||
},
|
||||
validSlotContent || (fallback ? fallback() : []),
|
||||
validSlotContent && (slots as RawSlots)._ === SlotFlags.STABLE
|
||||
|
|
Loading…
Reference in New Issue