Skip to content

Commit 503615a

Browse files
authored
feat(compiler): v-on event modifier (#8)
1 parent 853189c commit 503615a

File tree

7 files changed

+63
-3
lines changed

7 files changed

+63
-3
lines changed

packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap

+16
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ export function render() {
7171
"
7272
`;
7373

74+
exports[`compile > directives > v-on > event modifier 1`] = `
75+
"import { template, children, effect, withModifiers, on } from 'vue/vapor';
76+
const t0 = template('<div></div>');
77+
export function render() {
78+
const n0 = t0();
79+
const {
80+
0: [n1],
81+
} = children(n0);
82+
effect(() => {
83+
on(n1, 'click', withModifiers(handleClick, ['prevent', 'stop']));
84+
});
85+
return n0;
86+
}
87+
"
88+
`;
89+
7490
exports[`compile > directives > v-on > simple expression 1`] = `
7591
"import { template, children, effect, on } from 'vue/vapor';
7692
const t0 = template('<div></div>');

packages/compiler-vapor/__tests__/compile.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@ describe('compile', () => {
120120
},
121121
})
122122
})
123+
124+
test('event modifier', async () => {
125+
const code = await compile(
126+
`<div @click.prevent.stop="handleClick"></div>`,
127+
{
128+
bindingMetadata: {
129+
handleClick: BindingTypes.SETUP_CONST,
130+
},
131+
},
132+
)
133+
expect(code).matchSnapshot()
134+
})
123135
})
124136

125137
describe('v-html', () => {

packages/compiler-vapor/src/generate.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,14 @@ export function generate(
9898
}
9999

100100
case IRNodeTypes.SET_EVENT: {
101-
code = `on(n${oper.element}, ${JSON.stringify(oper.name)}, ${
102-
oper.value
103-
})\n`
101+
let value = oper.value
102+
if (oper.modifiers.length) {
103+
value = `withModifiers(${value}, ${genArrayExpression(
104+
oper.modifiers,
105+
)})`
106+
vaporHelpers.add('withModifiers')
107+
}
108+
code = `on(n${oper.element}, ${JSON.stringify(oper.name)}, ${value})\n`
104109
vaporHelpers.add('on')
105110
break
106111
}
@@ -172,3 +177,8 @@ function genChildren(children: DynamicChildren) {
172177
if (!code) return ''
173178
return `{${code}}`
174179
}
180+
181+
// TODO: other types (not only string)
182+
function genArrayExpression(elements: string[]) {
183+
return `[${elements.map((it) => `"${it}"`).join(', ')}]`
184+
}

packages/compiler-vapor/src/ir.ts

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export interface SetEventIRNode extends IRNode {
5959
element: number
6060
name: string
6161
value: string
62+
modifiers: string[]
6263
}
6364

6465
export interface SetHtmlIRNode extends IRNode {

packages/compiler-vapor/src/transform.ts

+1
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ function transformProp(
416416
element: ctx.reference(),
417417
name: node.arg.content,
418418
value: expr,
419+
modifiers,
419420
})
420421
break
421422
}

packages/runtime-vapor/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ export { effect } from './scheduler'
3939
export * from './on'
4040
export * from './render'
4141
export * from './template'
42+
export * from './scheduler'
43+
export { withModifiers } from '@vue/runtime-dom'

playground/src/event-modifier.vue

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script setup lang="ts">
2+
const handleClick = () => {
3+
console.log('Hello, Vapor!')
4+
}
5+
6+
// @ts-expect-error
7+
globalThis.handleClick = handleClick
8+
</script>
9+
10+
<template>
11+
<form>
12+
<button @click="handleClick">submit</button>
13+
</form>
14+
15+
<form>
16+
<button @click.prevent="handleClick">no submit</button>
17+
</form>
18+
</template>

0 commit comments

Comments
 (0)