From 692197be33de8f73a605e3a7f71389be42613ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=9C=C9=B4=D0=B2=CA=8F=D1=82=E1=B4=87?= Date: Wed, 14 Oct 2020 00:04:52 +0800 Subject: [PATCH] fix(compiler-core): fix v-if key injection with v-on object syntax (#2368) fix #2366 --- .../__tests__/transforms/vIf.spec.ts | 42 ++++++++++++++----- packages/compiler-core/src/utils.ts | 17 ++++++-- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/vIf.spec.ts b/packages/compiler-core/__tests__/transforms/vIf.spec.ts index a21ab1f019b..f1b91cc4567 100644 --- a/packages/compiler-core/__tests__/transforms/vIf.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vIf.spec.ts @@ -4,25 +4,25 @@ import { transformIf } from '../../src/transforms/vIf' import { transformElement } from '../../src/transforms/transformElement' import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet' import { - IfNode, - NodeTypes, - ElementNode, - TextNode, CommentNode, - SimpleExpressionNode, ConditionalExpression, - IfConditionalExpression, - VNodeCall, + ElementNode, ElementTypes, - IfBranchNode + IfBranchNode, + IfConditionalExpression, + IfNode, + NodeTypes, + SimpleExpressionNode, + TextNode, + VNodeCall } from '../../src/ast' import { ErrorCodes } from '../../src/errors' -import { CompilerOptions, generate } from '../../src' +import { CompilerOptions, generate, TO_HANDLERS } from '../../src' import { + CREATE_COMMENT, FRAGMENT, MERGE_PROPS, - RENDER_SLOT, - CREATE_COMMENT + RENDER_SLOT } from '../../src/runtimeHelpers' import { createObjectMatcher } from '../testUtils' @@ -673,4 +673,24 @@ describe('compiler: v-if', () => { expect((b1.children[3] as ElementNode).tag).toBe(`p`) }) }) + + test('v-on with v-if', () => { + const { + node: { codegenNode } + } = parseWithIfTransform( + `` + ) + + expect((codegenNode.consequent as any).props.type).toBe( + NodeTypes.JS_CALL_EXPRESSION + ) + expect((codegenNode.consequent as any).props.callee).toBe(MERGE_PROPS) + expect( + (codegenNode.consequent as any).props.arguments[0].properties[0].value + .content + ).toBe('0') + expect((codegenNode.consequent as any).props.arguments[1].callee).toBe( + TO_HANDLERS + ) + }) }) diff --git a/packages/compiler-core/src/utils.ts b/packages/compiler-core/src/utils.ts index 201ebe63aa3..efc97f5d4c4 100644 --- a/packages/compiler-core/src/utils.ts +++ b/packages/compiler-core/src/utils.ts @@ -29,7 +29,8 @@ import { TELEPORT, SUSPENSE, KEEP_ALIVE, - BASE_TRANSITION + BASE_TRANSITION, + TO_HANDLERS } from './runtimeHelpers' import { isString, isObject, hyphenate, extend } from '@vue/shared' @@ -215,7 +216,7 @@ export function injectProp( prop: Property, context: TransformContext ) { - let propsWithInjection: ObjectExpression | CallExpression + let propsWithInjection: ObjectExpression | CallExpression | undefined const props = node.type === NodeTypes.VNODE_CALL ? node.props : node.arguments[2] if (props == null || isString(props)) { @@ -228,9 +229,17 @@ export function injectProp( if (!isString(first) && first.type === NodeTypes.JS_OBJECT_EXPRESSION) { first.properties.unshift(prop) } else { - props.arguments.unshift(createObjectExpression([prop])) + if (props.callee === TO_HANDLERS) { + // #2366 + propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [ + createObjectExpression([prop]), + props + ]) + } else { + props.arguments.unshift(createObjectExpression([prop])) + } } - propsWithInjection = props + !propsWithInjection && (propsWithInjection = props) } else if (props.type === NodeTypes.JS_OBJECT_EXPRESSION) { let alreadyExists = false // check existing key to avoid overriding user provided keys