fix(slots): ensure different branches of dynamic slots have different keys
fix #6202
This commit is contained in:
@@ -17,6 +17,15 @@ describe('createSlot', () => {
|
||||
expect(actual).toEqual({ descriptor: slot })
|
||||
})
|
||||
|
||||
it('should attach key', () => {
|
||||
const dynamicSlot = [{ name: 'descriptor', fn: slot, key: '1' }]
|
||||
|
||||
const actual = createSlots(record, dynamicSlot)
|
||||
const ret = actual.descriptor()
|
||||
// @ts-ignore
|
||||
expect(ret.key).toBe('1')
|
||||
})
|
||||
|
||||
it('should add all slots to the record', () => {
|
||||
const dynamicSlot = [
|
||||
{ name: 'descriptor', fn: slot },
|
||||
|
||||
@@ -4,6 +4,7 @@ import { isArray } from '@vue/shared'
|
||||
interface CompiledSlotDescriptor {
|
||||
name: string
|
||||
fn: Slot
|
||||
key?: string
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,7 +28,15 @@ export function createSlots(
|
||||
}
|
||||
} else if (slot) {
|
||||
// conditional single slot generated by <template v-if="..." #foo>
|
||||
slots[slot.name] = slot.fn
|
||||
slots[slot.name] = slot.key
|
||||
? (...args: any[]) => {
|
||||
const res = slot.fn(...args)
|
||||
// attach branch key so each conditional branch is considered a
|
||||
// different fragment
|
||||
;(res as any).key = slot.key
|
||||
return res
|
||||
}
|
||||
: slot.fn
|
||||
}
|
||||
}
|
||||
return slots
|
||||
|
||||
@@ -66,7 +66,14 @@ export function renderSlot(
|
||||
const validSlotContent = slot && ensureValidVNode(slot(props))
|
||||
const rendered = createBlock(
|
||||
Fragment,
|
||||
{ key: props.key || `_${name}` },
|
||||
{
|
||||
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}`
|
||||
},
|
||||
validSlotContent || (fallback ? fallback() : []),
|
||||
validSlotContent && (slots as RawSlots)._ === SlotFlags.STABLE
|
||||
? PatchFlags.STABLE_FRAGMENT
|
||||
|
||||
Reference in New Issue
Block a user