diff --git a/packages/compiler-vapor/__tests__/generators/__snapshots__/component.spec.ts.snap b/packages/compiler-vapor/__tests__/generators/__snapshots__/component.spec.ts.snap index 999526e70..5e4e289d4 100644 --- a/packages/compiler-vapor/__tests__/generators/__snapshots__/component.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/generators/__snapshots__/component.spec.ts.snap @@ -1,5 +1,20 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`generate component > generate component with emits 1`] = ` +"import { toHandlerKey as _toHandlerKey } from 'vue'; +import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor'; + +export function render(_ctx) { + const n0 = _createComponent(_resolveComponent("Comp"), [{ + onClick: () => (fn) + }]) + const n1 = _createComponent(_resolveComponent("Comp"), [{ + [_toHandlerKey(eventName)]: () => (fn) + }]) + return [n0, n1] +}" +`; + exports[`generate component > generate multi root component 1`] = ` "import { resolveComponent as _resolveComponent, createComponent as _createComponent, template as _template } from 'vue/vapor'; const t0 = _template("123") diff --git a/packages/compiler-vapor/__tests__/generators/component.spec.ts b/packages/compiler-vapor/__tests__/generators/component.spec.ts index 9d6ded902..28aaf91b0 100644 --- a/packages/compiler-vapor/__tests__/generators/component.spec.ts +++ b/packages/compiler-vapor/__tests__/generators/component.spec.ts @@ -20,4 +20,12 @@ describe('generate component', () => { const { code } = compile(`
`) expect(code).toMatchSnapshot() }) + + test('generate component with emits', () => { + const { code } = compile(` + + + `) + expect(code).toMatchSnapshot() + }) }) diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts index 8fcaf28bc..e2f1ab53e 100644 --- a/packages/compiler-vapor/src/generators/prop.ts +++ b/packages/compiler-vapor/src/generators/prop.ts @@ -86,7 +86,7 @@ function genLiteralObjectProps( } export function genPropKey( - { key: node, runtimeCamelize, modifier }: IRProp, + { key: node, modifier, runtimeCamelize, runtimeHandler }: IRProp, context: CodegenContext, ): CodeFragment[] { const { helper } = context @@ -104,13 +104,14 @@ export function genPropKey( ] } - const key = genExpression(node, context) - return [ - '[', - modifier && `${JSON.stringify(modifier)} + `, - ...(runtimeCamelize ? genCall(helper('camelize'), key) : key), - ']', - ] + let key = genExpression(node, context) + if (runtimeCamelize) { + key = genCall(helper('camelize'), key) + } + if (runtimeHandler) { + key = genCall(helper('toHandlerKey'), key) + } + return ['[', modifier && `${JSON.stringify(modifier)} + `, ...key, ']'] } function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) { diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 5ffee61ed..b88b01055 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -43,6 +43,7 @@ export interface DirectiveTransformResult { value: SimpleExpressionNode modifier?: '.' | '^' runtimeCamelize?: boolean + runtimeHandler?: boolean } // A structural directive transform is technically also a NodeTransform; diff --git a/packages/compiler-vapor/src/transforms/vOn.ts b/packages/compiler-vapor/src/transforms/vOn.ts index d758754ed..4032882e9 100644 --- a/packages/compiler-vapor/src/transforms/vOn.ts +++ b/packages/compiler-vapor/src/transforms/vOn.ts @@ -1,9 +1,14 @@ -import { ErrorCodes, createCompilerError } from '@vue/compiler-dom' +import { + ElementTypes, + ErrorCodes, + createCompilerError, +} from '@vue/compiler-dom' import type { DirectiveTransform } from '../transform' import { IRNodeTypes, type KeyOverride, type SetEventIRNode } from '../ir' import { resolveModifiers } from '@vue/compiler-dom' -import { extend, makeMap } from '@vue/shared' +import { extend, makeMap, toHandlerKey } from '@vue/shared' import { resolveExpression } from '../utils' +import { EMPTY_EXPRESSION } from './utils' const delegatedEvents = /*#__PURE__*/ makeMap( 'beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,' + @@ -14,6 +19,8 @@ const delegatedEvents = /*#__PURE__*/ makeMap( export const transformVOn: DirectiveTransform = (dir, node, context) => { let { arg, exp, loc, modifiers } = dir + const isComponent = node.tagType === ElementTypes.COMPONENT + if (!exp && (!modifiers.length || !arg)) { context.options.onError( createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc), @@ -70,6 +77,18 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => { } } + if (isComponent) { + if (arg.isStatic) { + arg = extend({}, arg, { content: toHandlerKey(arg.content) }) + } + const handler = exp || EMPTY_EXPRESSION + return { + key: arg, + value: handler, + runtimeHandler: !arg.isStatic, + } + } + const operation: SetEventIRNode = { type: IRNodeTypes.SET_EVENT, element: context.reference(),