fix(slots): ensure different branches of dynamic slots have different keys

fix #6202
This commit is contained in:
Evan You
2022-08-30 15:55:09 +08:00
parent 96eb745254
commit 00036bb52c
8 changed files with 69 additions and 20 deletions

View File

@@ -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 },

View File

@@ -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

View File

@@ -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