feat(compiler): v-on event modifier (#8)
This commit is contained in:
parent
853189c6ac
commit
503615a31e
|
@ -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>');
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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(', ')}]`
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ export interface SetEventIRNode extends IRNode {
|
|||
element: number
|
||||
name: string
|
||||
value: string
|
||||
modifiers: string[]
|
||||
}
|
||||
|
||||
export interface SetHtmlIRNode extends IRNode {
|
||||
|
|
|
@ -416,6 +416,7 @@ function transformProp(
|
|||
element: ctx.reference(),
|
||||
name: node.arg.content,
|
||||
value: expr,
|
||||
modifiers,
|
||||
})
|
||||
break
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue