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(),