diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts index 218281ba762..bc2cf9eae6c 100644 --- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts @@ -437,6 +437,135 @@ describe('compiler: transform v-on', () => { }) }) + test('should handle inline arrow function expression wrapped in parentheses', () => { + const { node } = parseWithVOn(`
`) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(foo => bar = foo)' + }) + }) + + test('should handle inline arrow function expression wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '((foo: any): any => bar = foo)' + }) + }) + + test('should handle inline function expression wrapped in parentheses', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(function (foo) { bar = foo })' + }) + }) + + test('should handle inline function expression wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(function (foo: any): any { bar = foo })' + }) + }) + + test('should handle inline async arrow function expression with parameters', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'async foo => await fetch(foo)' + }) + }) + + test('should handle inline async arrow function expression with parameters (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'async (foo: any): Promise => await fetch(foo)' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(async foo => await fetch(foo))' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(async (foo: any): Promise => await fetch(foo))' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(async function (foo) {\nawait fetch(foo)\nbar = foo\n})' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: + '(async function (foo: any): Promise {\nawait fetch(foo)\nbar = foo\n}})' + }) + }) + // TODO remove in 3.4 test('case conversion for vnode hooks', () => { const { node } = parseWithVOn(`
`) diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index 3deee202418..2d341c80781 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -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*(?::[^=]+)?=>|(?:async\s+)?function(?:\s+[\w$_]+)?\s*\([^)]*?\)\s*(?::[^=]+)?{))[\s\S]+\)*/ export interface VOnDirectiveNode extends DirectiveNode { // v-on without arg is handled directly in ./transformElements.ts due to it affecting