feat(compiler): v-on event modifier (#8)

This commit is contained in:
ubugeeei 2023-11-30 06:11:59 +09:00 committed by GitHub
parent 853189c6ac
commit 503615a31e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 3 deletions

View File

@ -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('<div></div>');
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('<div></div>');

View File

@ -120,6 +120,18 @@ describe('compile', () => {
},
})
})
test('event modifier', async () => {
const code = await compile(
`<div @click.prevent.stop="handleClick"></div>`,
{
bindingMetadata: {
handleClick: BindingTypes.SETUP_CONST,
},
},
)
expect(code).matchSnapshot()
})
})
describe('v-html', () => {

View File

@ -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(', ')}]`
}

View File

@ -59,6 +59,7 @@ export interface SetEventIRNode extends IRNode {
element: number
name: string
value: string
modifiers: string[]
}
export interface SetHtmlIRNode extends IRNode {

View File

@ -416,6 +416,7 @@ function transformProp(
element: ctx.reference(),
name: node.arg.content,
value: expr,
modifiers,
})
break
}

View File

@ -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'

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
const handleClick = () => {
console.log('Hello, Vapor!')
}
// @ts-expect-error
globalThis.handleClick = handleClick
</script>
<template>
<form>
<button @click="handleClick">submit</button>
</form>
<form>
<button @click.prevent="handleClick">no submit</button>
</form>
</template>