]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): add support for arrow aysnc function with unbracketed (#5789)
authorhuangcheng <1530844743@qq.com>
Mon, 29 Apr 2024 10:55:58 +0000 (18:55 +0800)
committerGitHub <noreply@github.com>
Mon, 29 Apr 2024 10:55:58 +0000 (18:55 +0800)
close #5788

packages/compiler-core/__tests__/transforms/vOn.spec.ts
packages/compiler-core/src/transforms/vOn.ts

index 568fa0b5a8c53f78518adf104eccc36463269e35..b1c37e3f74e46d372460108d6a097b839fe297e2 100644 (file)
@@ -286,6 +286,23 @@ describe('compiler: transform v-on', () => {
     })
   })
 
+  test('should NOT wrap as function if expression is already function expression (async)', () => {
+    const { node } = parseWithVOn(
+      `<div @click="async $event => await foo($event)"/>`,
+    )
+    expect((node.codegenNode as VNodeCall).props).toMatchObject({
+      properties: [
+        {
+          key: { content: `onClick` },
+          value: {
+            type: NodeTypes.SIMPLE_EXPRESSION,
+            content: `async $event => await foo($event)`,
+          },
+        },
+      ],
+    })
+  })
+
   test('should NOT wrap as function if expression is already function expression (with newlines)', () => {
     const { node } = parseWithVOn(
       `<div @click="
@@ -630,6 +647,39 @@ describe('compiler: transform v-on', () => {
       })
     })
 
+    test('inline async arrow function with no bracket expression handler', () => {
+      const { root, node } = parseWithVOn(
+        `<div v-on:click="async e => await foo(e)" />`,
+        {
+          prefixIdentifiers: true,
+          cacheHandlers: true,
+        },
+      )
+
+      expect(root.cached).toBe(1)
+      const vnodeCall = node.codegenNode as VNodeCall
+      // should not treat cached handler as dynamicProp, so no flags
+      expect(vnodeCall.patchFlag).toBeUndefined()
+      expect(
+        (vnodeCall.props as ObjectExpression).properties[0].value,
+      ).toMatchObject({
+        type: NodeTypes.JS_CACHE_EXPRESSION,
+        index: 0,
+        value: {
+          type: NodeTypes.COMPOUND_EXPRESSION,
+          children: [
+            `async `,
+            { content: `e` },
+            ` => await `,
+            { content: `_ctx.foo` },
+            `(`,
+            { content: `e` },
+            `)`,
+          ],
+        },
+      })
+    })
+
     test('inline async function expression handler', () => {
       const { root, node } = parseWithVOn(
         `<div v-on:click="async function () { await foo() } " />`,
index 8c13bdae524bb63dd76dec20bd9e48dd5e731118..a1631e10db30d3cc9cf225abe88f500a121ad8e2 100644 (file)
@@ -17,7 +17,7 @@ import { hasScopeRef, isMemberExpression } from '../utils'
 import { TO_HANDLER_KEY } from '../runtimeHelpers'
 
 const fnExpRE =
-  /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/
+  /^\s*(async\s*)?(\([^)]*?\)|[\w$_]+)\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/
 
 export interface VOnDirectiveNode extends DirectiveNode {
   // v-on without arg is handled directly in ./transformElements.ts due to it affecting