fix(slots): ensure different branches of dynamic slots have different keys
fix #6202
This commit is contained in:
@@ -43,7 +43,8 @@ export function render(_ctx, _cache) {
|
||||
name: \\"foo\\",
|
||||
fn: _withCtx(() => [
|
||||
_createElementVNode(\\"div\\")
|
||||
])
|
||||
]),
|
||||
key: \\"0\\"
|
||||
}
|
||||
: undefined,
|
||||
_renderList(_ctx.list, (i) => {
|
||||
|
||||
@@ -56,7 +56,8 @@ return function render(_ctx, _cache) {
|
||||
(_ctx.ok)
|
||||
? {
|
||||
name: \\"one\\",
|
||||
fn: _withCtx((props) => [_toDisplayString(props)])
|
||||
fn: _withCtx((props) => [_toDisplayString(props)]),
|
||||
key: \\"0\\"
|
||||
}
|
||||
: undefined
|
||||
]), 1024 /* DYNAMIC_SLOTS */))
|
||||
@@ -76,16 +77,19 @@ return function render(_ctx, _cache) {
|
||||
ok
|
||||
? {
|
||||
name: \\"one\\",
|
||||
fn: _withCtx(() => [\\"foo\\"])
|
||||
fn: _withCtx(() => [\\"foo\\"]),
|
||||
key: \\"0\\"
|
||||
}
|
||||
: orNot
|
||||
? {
|
||||
name: \\"two\\",
|
||||
fn: _withCtx((props) => [\\"bar\\"])
|
||||
fn: _withCtx((props) => [\\"bar\\"]),
|
||||
key: \\"1\\"
|
||||
}
|
||||
: {
|
||||
name: \\"one\\",
|
||||
fn: _withCtx(() => [\\"baz\\"])
|
||||
fn: _withCtx(() => [\\"baz\\"]),
|
||||
key: \\"2\\"
|
||||
}
|
||||
]), 1024 /* DYNAMIC_SLOTS */))
|
||||
}
|
||||
@@ -105,7 +109,8 @@ return function render(_ctx, _cache) {
|
||||
ok
|
||||
? {
|
||||
name: \\"one\\",
|
||||
fn: _withCtx(() => [\\"hello\\"])
|
||||
fn: _withCtx(() => [\\"hello\\"]),
|
||||
key: \\"0\\"
|
||||
}
|
||||
: undefined
|
||||
]), 1024 /* DYNAMIC_SLOTS */))
|
||||
|
||||
@@ -568,7 +568,8 @@ describe('compiler: transform component slots', () => {
|
||||
fn: {
|
||||
type: NodeTypes.JS_FUNCTION_EXPRESSION,
|
||||
returns: [{ type: NodeTypes.TEXT, content: `hello` }]
|
||||
}
|
||||
},
|
||||
key: `0`
|
||||
}),
|
||||
alternate: {
|
||||
content: `undefined`,
|
||||
@@ -616,7 +617,8 @@ describe('compiler: transform component slots', () => {
|
||||
content: { content: `props` }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
key: `0`
|
||||
}),
|
||||
alternate: {
|
||||
content: `undefined`,
|
||||
@@ -660,7 +662,8 @@ describe('compiler: transform component slots', () => {
|
||||
type: NodeTypes.JS_FUNCTION_EXPRESSION,
|
||||
params: undefined,
|
||||
returns: [{ type: NodeTypes.TEXT, content: `foo` }]
|
||||
}
|
||||
},
|
||||
key: `0`
|
||||
}),
|
||||
alternate: {
|
||||
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
|
||||
@@ -671,7 +674,8 @@ describe('compiler: transform component slots', () => {
|
||||
type: NodeTypes.JS_FUNCTION_EXPRESSION,
|
||||
params: { content: `props` },
|
||||
returns: [{ type: NodeTypes.TEXT, content: `bar` }]
|
||||
}
|
||||
},
|
||||
key: `1`
|
||||
}),
|
||||
alternate: createObjectMatcher({
|
||||
name: `one`,
|
||||
@@ -679,7 +683,8 @@ describe('compiler: transform component slots', () => {
|
||||
type: NodeTypes.JS_FUNCTION_EXPRESSION,
|
||||
params: undefined,
|
||||
returns: [{ type: NodeTypes.TEXT, content: `baz` }]
|
||||
}
|
||||
},
|
||||
key: `2`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ export function buildSlots(
|
||||
let hasNamedDefaultSlot = false
|
||||
const implicitDefaultChildren: TemplateChildNode[] = []
|
||||
const seenSlotNames = new Set<string>()
|
||||
let conditionalBranchIndex = 0
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const slotElement = children[i]
|
||||
@@ -210,7 +211,7 @@ export function buildSlots(
|
||||
dynamicSlots.push(
|
||||
createConditionalExpression(
|
||||
vIf.exp!,
|
||||
buildDynamicSlot(slotName, slotFunction),
|
||||
buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++),
|
||||
defaultFallback
|
||||
)
|
||||
)
|
||||
@@ -243,10 +244,14 @@ export function buildSlots(
|
||||
conditional.alternate = vElse.exp
|
||||
? createConditionalExpression(
|
||||
vElse.exp,
|
||||
buildDynamicSlot(slotName, slotFunction),
|
||||
buildDynamicSlot(
|
||||
slotName,
|
||||
slotFunction,
|
||||
conditionalBranchIndex++
|
||||
),
|
||||
defaultFallback
|
||||
)
|
||||
: buildDynamicSlot(slotName, slotFunction)
|
||||
: buildDynamicSlot(slotName, slotFunction, conditionalBranchIndex++)
|
||||
} else {
|
||||
context.onError(
|
||||
createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, vElse.loc)
|
||||
@@ -369,12 +374,19 @@ export function buildSlots(
|
||||
|
||||
function buildDynamicSlot(
|
||||
name: ExpressionNode,
|
||||
fn: FunctionExpression
|
||||
fn: FunctionExpression,
|
||||
index?: number
|
||||
): ObjectExpression {
|
||||
return createObjectExpression([
|
||||
const props = [
|
||||
createObjectProperty(`name`, name),
|
||||
createObjectProperty(`fn`, fn)
|
||||
])
|
||||
]
|
||||
if (index != null) {
|
||||
props.push(
|
||||
createObjectProperty(`key`, createSimpleExpression(String(index), true))
|
||||
)
|
||||
}
|
||||
return createObjectExpression(props)
|
||||
}
|
||||
|
||||
function hasForwardedSlots(children: TemplateChildNode[]): boolean {
|
||||
|
||||
Reference in New Issue
Block a user