]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): fix v-if key injection with v-on object syntax (#2368)
authorᴜɴвʏтᴇ <i@shangyes.net>
Tue, 13 Oct 2020 16:04:52 +0000 (00:04 +0800)
committerGitHub <noreply@github.com>
Tue, 13 Oct 2020 16:04:52 +0000 (12:04 -0400)
fix #2366

packages/compiler-core/__tests__/transforms/vIf.spec.ts
packages/compiler-core/src/utils.ts

index a21ab1f019bf5456636b2d1c950eccfbcf45f6fb..f1b91cc4567dbdfdbc4f9dfe3d1d35c424047527 100644 (file)
@@ -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(
+      `<button v-on="{ click: clickEvent }" v-if="true">w/ v-if</button>`
+    )
+
+    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
+    )
+  })
 })
index 201ebe63aa32f00e154a24dcdfbd3dd52509847c..efc97f5d4c4bd1ff5f091385bc4444764f82878e 100644 (file)
@@ -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