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( + ` + `, + ) + 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( + ` + `, + ) + 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