diff --git a/packages/compiler-core/__tests__/transforms/vIf.spec.ts b/packages/compiler-core/__tests__/transforms/vIf.spec.ts
index 2c2fedab0d5..c35c397798f 100644
--- a/packages/compiler-core/__tests__/transforms/vIf.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vIf.spec.ts
@@ -757,4 +757,74 @@ describe('compiler: v-if', () => {
TO_HANDLERS,
)
})
+
+ test('template v-if + dynamic key', () => {
+ const {
+ node: { codegenNode: codegenNode },
+ } = parseWithIfTransform(
+ `aaaaaaaaaaaaa
+ bbbbbbbbbbb`,
+ )
+ expect(codegenNode.alternate).toMatchObject({
+ props: {
+ properties: [
+ {
+ key: { content: 'key' },
+ value: {
+ content: '2000',
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ })
+ expect(codegenNode.consequent).toMatchObject({
+ props: {
+ properties: [
+ {
+ key: { content: 'key' },
+ value: {
+ content: '100',
+ isStatic: false,
+ },
+ },
+ ],
+ },
+ })
+ })
+
+ test('template is static key with v-if', () => {
+ const {
+ node: { codegenNode: codegenNode },
+ } = parseWithIfTransform(
+ `aaaaaaaaaaaaa
+ bbbbbbbbbbb`,
+ )
+ expect(codegenNode.alternate).toMatchObject({
+ props: {
+ properties: [
+ {
+ key: { content: 'key' },
+ value: {
+ content: 'bb',
+ isStatic: true,
+ },
+ },
+ ],
+ },
+ })
+ expect(codegenNode.consequent).toMatchObject({
+ props: {
+ properties: [
+ {
+ key: { content: 'key' },
+ value: {
+ content: 'aa',
+ isStatic: true,
+ },
+ },
+ ],
+ },
+ })
+ })
})
diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts
index 716da46c99b..1e94487c900 100644
--- a/packages/compiler-core/src/transforms/transformExpression.ts
+++ b/packages/compiler-core/src/transforms/transformExpression.ts
@@ -11,6 +11,7 @@ import type { NodeTransform, TransformContext } from '../transform'
import {
type CompoundExpressionNode,
ConstantTypes,
+ type DirectiveNode,
type ExpressionNode,
NodeTypes,
type SimpleExpressionNode,
@@ -79,6 +80,18 @@ export const transformExpression: NodeTransform = (node, context) => {
}
}
}
+ } else if (node.type === NodeTypes.IF_BRANCH) {
+ if (node.isTemplateIf && node.userKey && node.userKey.name === 'bind') {
+ const useKey = node.userKey as DirectiveNode
+ const exp = useKey.exp
+ const arg = useKey.arg
+ if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION) {
+ useKey.exp = processExpression(exp, context, false)
+ }
+ if (arg && arg.type === NodeTypes.SIMPLE_EXPRESSION && !arg.isStatic) {
+ useKey.arg = processExpression(arg, context)
+ }
+ }
}
}
diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts
index c3dc8d4ecd0..175770c9bcb 100644
--- a/packages/compiler-core/src/transforms/vIf.ts
+++ b/packages/compiler-core/src/transforms/vIf.ts
@@ -243,13 +243,29 @@ function createChildrenCodegenNode(
context: TransformContext,
): BlockCodegenNode | MemoExpression {
const { helper } = context
+
+ let userKey = ''
+ let isStatic = false
+ if (branch.userKey && branch.userKey.name === 'bind') {
+ userKey = ((branch.userKey as DirectiveNode).exp as SimpleExpressionNode)
+ .content
+ }
+ if (
+ branch.userKey &&
+ branch.userKey.name === 'key' &&
+ (branch.userKey as AttributeNode).value
+ ) {
+ isStatic = true
+ userKey = `${(branch.userKey as AttributeNode).value!.content}`
+ }
+
const keyProperty = createObjectProperty(
`key`,
createSimpleExpression(
- `${keyIndex}`,
- false,
+ `${userKey || keyIndex}`,
+ isStatic,
locStub,
- ConstantTypes.CAN_CACHE,
+ userKey ? ConstantTypes.NOT_CONSTANT : ConstantTypes.CAN_CACHE,
),
)
const { children } = branch