diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap index 92181bc6e..4f9dbf8d2 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap @@ -71,6 +71,22 @@ export function render() { " `; +exports[`compile > directives > v-on > event modifier 1`] = ` +"import { template, children, effect, withModifiers, on } from 'vue/vapor'; +const t0 = template('
'); +export function render() { + const n0 = t0(); + const { + 0: [n1], + } = children(n0); + effect(() => { + on(n1, 'click', withModifiers(handleClick, ['prevent', 'stop'])); + }); + return n0; +} +" +`; + exports[`compile > directives > v-on > simple expression 1`] = ` "import { template, children, effect, on } from 'vue/vapor'; const t0 = template('
'); diff --git a/packages/compiler-vapor/__tests__/compile.test.ts b/packages/compiler-vapor/__tests__/compile.test.ts index e9766a806..8fa34b5ed 100644 --- a/packages/compiler-vapor/__tests__/compile.test.ts +++ b/packages/compiler-vapor/__tests__/compile.test.ts @@ -120,6 +120,18 @@ describe('compile', () => { }, }) }) + + test('event modifier', async () => { + const code = await compile( + `
`, + { + bindingMetadata: { + handleClick: BindingTypes.SETUP_CONST, + }, + }, + ) + expect(code).matchSnapshot() + }) }) describe('v-html', () => { diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 0af9d764b..e21f0f02b 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -98,9 +98,14 @@ export function generate( } case IRNodeTypes.SET_EVENT: { - code = `on(n${oper.element}, ${JSON.stringify(oper.name)}, ${ - oper.value - })\n` + let value = oper.value + if (oper.modifiers.length) { + value = `withModifiers(${value}, ${genArrayExpression( + oper.modifiers, + )})` + vaporHelpers.add('withModifiers') + } + code = `on(n${oper.element}, ${JSON.stringify(oper.name)}, ${value})\n` vaporHelpers.add('on') break } @@ -172,3 +177,8 @@ function genChildren(children: DynamicChildren) { if (!code) return '' return `{${code}}` } + +// TODO: other types (not only string) +function genArrayExpression(elements: string[]) { + return `[${elements.map((it) => `"${it}"`).join(', ')}]` +} diff --git a/packages/compiler-vapor/src/ir.ts b/packages/compiler-vapor/src/ir.ts index b3892a3cd..31deb1e4d 100644 --- a/packages/compiler-vapor/src/ir.ts +++ b/packages/compiler-vapor/src/ir.ts @@ -59,6 +59,7 @@ export interface SetEventIRNode extends IRNode { element: number name: string value: string + modifiers: string[] } export interface SetHtmlIRNode extends IRNode { diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index d7f5b7f1a..d304c2896 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -416,6 +416,7 @@ function transformProp( element: ctx.reference(), name: node.arg.content, value: expr, + modifiers, }) break } diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts index 9e47af592..0eebcbbf8 100644 --- a/packages/runtime-vapor/src/index.ts +++ b/packages/runtime-vapor/src/index.ts @@ -39,3 +39,5 @@ export { effect } from './scheduler' export * from './on' export * from './render' export * from './template' +export * from './scheduler' +export { withModifiers } from '@vue/runtime-dom' diff --git a/playground/src/event-modifier.vue b/playground/src/event-modifier.vue new file mode 100644 index 000000000..97e6fe3af --- /dev/null +++ b/playground/src/event-modifier.vue @@ -0,0 +1,18 @@ + + +