refactor: simplify event handler

This commit is contained in:
三咲智子 Kevin Deng 2024-02-07 01:37:07 +08:00
parent ef12b99d0c
commit 38865c7ca1
No known key found for this signature in database
GPG Key ID: 69992F2250DFD93E
12 changed files with 265 additions and 168 deletions

View File

@ -203,7 +203,7 @@ export function render(_ctx) {
_prepend(n4, n1) _prepend(n4, n1)
_insert(n2, n4, n5) _insert(n2, n4, n5)
_append(n4, n3) _append(n4, n3)
_on(n4, "click", (...args) => (_ctx.handleClick && _ctx.handleClick(...args))) _on(n4, "click", () => _ctx.handleClick)
_renderEffect(() => { _renderEffect(() => {
_setText(n1, _ctx.count) _setText(n1, _ctx.count)
_setText(n2, _ctx.count) _setText(n2, _ctx.count)

View File

@ -11,7 +11,7 @@ export function render(_ctx) {
const n1 = _createFor(() => (_ctx.items), (_block) => { const n1 = _createFor(() => (_ctx.items), (_block) => {
const n2 = t0() const n2 = t0()
const { 0: [n3],} = _children(n2) const { 0: [n3],} = _children(n2)
_on(n3, "click", $event => (_ctx.remove(_block.s[0]))) _on(n3, "click", () => $event => (_ctx.remove(_block.s[0])))
_renderEffect(() => { _renderEffect(() => {
const [item] = _block.s const [item] = _block.s
_setText(n3, item) _setText(n3, item)

View File

@ -8,7 +8,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "fooBar", (...args) => (_ctx.onMount && _ctx.onMount(...args))) _on(n1, "fooBar", () => _ctx.onMount)
return n0 return n0
}" }"
`; `;
@ -21,7 +21,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", (...args) => (_ctx.a['b' + _ctx.c] && _ctx.a['b' + _ctx.c](...args))) _on(n1, "click", () => _ctx.a['b' + _ctx.c])
return n0 return n0
}" }"
`; `;
@ -34,7 +34,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_renderEffect(() => _on(n1, _ctx.event, (...args) => (_ctx.handler && _ctx.handler(...args)))) _renderEffect(() => _on(n1, _ctx.event, () => _ctx.handler))
return n0 return n0
}" }"
`; `;
@ -47,7 +47,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_renderEffect(() => _on(n1, _ctx.event(_ctx.foo), (...args) => (_ctx.handler && _ctx.handler(...args)))) _renderEffect(() => _on(n1, _ctx.event(_ctx.foo), () => _ctx.handler))
return n0 return n0
}" }"
`; `;
@ -60,41 +60,80 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_renderEffect(() => _on(n1, _ctx.event, (...args) => (_ctx.handler && _ctx.handler(...args)))) _renderEffect(() => _on(n1, _ctx.event, () => _ctx.handler))
return n0 return n0
}" }"
`; `;
exports[`v-on > event modifier 1`] = ` exports[`v-on > event modifier 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, on as _on, withKeys as _withKeys } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<a></a><form></form><a></a><div></div><div></div><a></a><div></div><input><input><input><input><input><input><input><input><input><input><input><input><input><input><input>") const t0 = _template("<a></a><form></form><a></a><div></div><div></div><a></a><div></div><input><input><input><input><input><input><input><input><input><input><input><input><input><input><input>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1], 1: [n2], 2: [n3], 3: [n4], 4: [n5], 5: [n6], 6: [n7], 7: [n8], 8: [n9], 9: [n10], 10: [n11], 11: [n12], 12: [n13], 13: [n14], 14: [n15], 15: [n16], 16: [n17], 17: [n18], 18: [n19], 19: [n20], 20: [n21], 21: [n22],} = _children(n0) const { 0: [n1], 1: [n2], 2: [n3], 3: [n4], 4: [n5], 5: [n6], 6: [n7], 7: [n8], 8: [n9], 9: [n10], 10: [n11], 11: [n12], 12: [n13], 13: [n14], 14: [n15], 15: [n16], 16: [n17], 17: [n18], 18: [n19], 19: [n20], 20: [n21], 21: [n22],} = _children(n0)
_on(n1, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["stop"])) _on(n1, "click", () => _ctx.handleEvent, undefined, {
_on(n2, "submit", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["prevent"])) modifiers: ["stop"]
_on(n3, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["stop", "prevent"])) })
_on(n4, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["self"])) _on(n2, "submit", () => _ctx.handleEvent, undefined, {
_on(n5, "click", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { capture: true }) modifiers: ["prevent"]
_on(n6, "click", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { once: true }) })
_on(n7, "scroll", (...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), { passive: true }) _on(n3, "click", () => _ctx.handleEvent, undefined, {
_on(n8, "contextmenu", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["right"])) modifiers: ["stop", "prevent"]
_on(n9, "click", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["left"])) })
_on(n10, "mouseup", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["middle"])) _on(n4, "click", () => _ctx.handleEvent, undefined, {
_on(n11, "contextmenu", _withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["right"])) modifiers: ["self"]
_on(n12, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["enter"])) })
_on(n13, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["tab"])) _on(n5, "click", () => _ctx.handleEvent, { capture: true })
_on(n14, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["delete"])) _on(n6, "click", () => _ctx.handleEvent, { once: true })
_on(n15, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["esc"])) _on(n7, "scroll", () => _ctx.handleEvent, { passive: true })
_on(n16, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["space"])) _on(n8, "contextmenu", () => _ctx.handleEvent, undefined, {
_on(n17, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["up"])) modifiers: ["right"]
_on(n18, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["down"])) })
_on(n19, "keyup", _withKeys((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["left"])) _on(n9, "click", () => _ctx.handleEvent, undefined, {
_on(n20, "keyup", _withModifiers((...args) => (_ctx.submit && _ctx.submit(...args)), ["middle"])) modifiers: ["left"]
_on(n21, "keyup", _withModifiers((...args) => (_ctx.submit && _ctx.submit(...args)), ["middle", "self"])) })
_on(n22, "keyup", _withKeys(_withModifiers((...args) => (_ctx.handleEvent && _ctx.handleEvent(...args)), ["self"]), ["enter"])) _on(n10, "mouseup", () => _ctx.handleEvent, undefined, {
modifiers: ["middle"]
})
_on(n11, "contextmenu", () => _ctx.handleEvent, undefined, {
modifiers: ["right"]
})
_on(n12, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["enter"]
})
_on(n13, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["tab"]
})
_on(n14, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["delete"]
})
_on(n15, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["esc"]
})
_on(n16, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["space"]
})
_on(n17, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["up"]
})
_on(n18, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["down"]
})
_on(n19, "keyup", () => _ctx.handleEvent, undefined, {
keys: ["left"]
})
_on(n20, "keyup", () => _ctx.submit, undefined, {
modifiers: ["middle"]
})
_on(n21, "keyup", () => _ctx.submit, undefined, {
modifiers: ["middle", "self"]
})
_on(n22, "keyup", () => _ctx.handleEvent, undefined, {
modifiers: ["self"],
keys: ["enter"]
})
return n0 return n0
}" }"
`; `;
@ -107,7 +146,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", e => _ctx.foo(e)) _on(n1, "click", () => e => _ctx.foo(e))
return n0 return n0
}" }"
`; `;
@ -120,7 +159,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => (_ctx.foo($event))) _on(n1, "click", () => $event => (_ctx.foo($event)))
return n0 return n0
}" }"
`; `;
@ -133,7 +172,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => {_ctx.foo($event);_ctx.bar()}) _on(n1, "click", () => $event => {_ctx.foo($event);_ctx.bar()})
return n0 return n0
}" }"
`; `;
@ -146,7 +185,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => {_ctx.i++;_ctx.foo($event)}) _on(n1, "click", () => $event => {_ctx.i++;_ctx.foo($event)})
return n0 return n0
}" }"
`; `;
@ -159,7 +198,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", (e: any): any => _ctx.foo(e)) _on(n1, "click", () => (e: any): any => _ctx.foo(e))
return n0 return n0
}" }"
`; `;
@ -172,7 +211,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", _on(n1, "click", () =>
$event => { $event => {
_ctx.foo($event) _ctx.foo($event)
} }
@ -189,7 +228,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => _ctx.foo($event)) _on(n1, "click", () => $event => _ctx.foo($event))
return n0 return n0
}" }"
`; `;
@ -202,7 +241,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", (...args) => (_ctx.a['b' + _ctx.c] && _ctx.a['b' + _ctx.c](...args))) _on(n1, "click", () => _ctx.a['b' + _ctx.c])
return n0 return n0
}" }"
`; `;
@ -215,7 +254,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => { _on(n1, "click", () => $event => {
_ctx.foo(); _ctx.foo();
_ctx.bar() _ctx.bar()
}) })
@ -231,7 +270,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => {_ctx.foo();_ctx.bar()}) _on(n1, "click", () => $event => {_ctx.foo();_ctx.bar()})
return n0 return n0
}" }"
`; `;
@ -244,99 +283,118 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", (...args) => (_ctx.foo.bar && _ctx.foo.bar(...args))) _on(n1, "click", () => _ctx.foo.bar)
return n0 return n0
}" }"
`; `;
exports[`v-on > should not wrap keys guard if no key modifier is present 1`] = ` exports[`v-on > should not wrap keys guard if no key modifier is present 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "keyup", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["exact"])) _on(n1, "keyup", () => _ctx.test, undefined, {
modifiers: ["exact"]
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should support multiple events and modifiers options w/ prefixIdentifiers: true 1`] = ` exports[`v-on > should support multiple events and modifiers options w/ prefixIdentifiers: true 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, on as _on, withKeys as _withKeys } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop"])) _on(n1, "click", () => _ctx.test, undefined, {
_on(n1, "keyup", _withKeys((...args) => (_ctx.test && _ctx.test(...args)), ["enter"])) modifiers: ["stop"]
})
_on(n1, "keyup", () => _ctx.test, undefined, {
keys: ["enter"]
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should support multiple modifiers and event options w/ prefixIdentifiers: true 1`] = ` exports[`v-on > should support multiple modifiers and event options w/ prefixIdentifiers: true 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop", "prevent"]), { capture: true, once: true }) _on(n1, "click", () => _ctx.test, { capture: true, once: true }, {
modifiers: ["stop", "prevent"]
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should transform click.middle 1`] = ` exports[`v-on > should transform click.middle 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "mouseup", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["middle"])) _on(n1, "mouseup", () => _ctx.test, undefined, {
modifiers: ["middle"]
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should transform click.middle 2`] = ` exports[`v-on > should transform click.middle 2`] = `
"import { template as _template, children as _children, renderEffect as _renderEffect, withModifiers as _withModifiers, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, renderEffect as _renderEffect, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_renderEffect(() => _on(n1, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["middle"]))) _renderEffect(() => {
_on(n1, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _ctx.test, undefined, {
modifiers: ["middle"]
})})
return n0 return n0
}" }"
`; `;
exports[`v-on > should transform click.right 1`] = ` exports[`v-on > should transform click.right 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "contextmenu", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["right"])) _on(n1, "contextmenu", () => _ctx.test, undefined, {
modifiers: ["right"]
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should transform click.right 2`] = ` exports[`v-on > should transform click.right 2`] = `
"import { template as _template, children as _children, renderEffect as _renderEffect, withModifiers as _withModifiers, withKeys as _withKeys, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, renderEffect as _renderEffect, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_renderEffect(() => _on(n1, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), _withKeys(_withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["right"]), ["right"]))) _renderEffect(() => {
_on(n1, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _ctx.test, undefined, {
modifiers: ["right"],
keys: ["right"]
})})
return n0 return n0
}" }"
`; `;
@ -349,20 +407,24 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", $event => (_ctx.i++)) _on(n1, "click", () => $event => (_ctx.i++))
return n0 return n0
}" }"
`; `;
exports[`v-on > should wrap both for dynamic key event w/ left/right modifiers 1`] = ` exports[`v-on > should wrap both for dynamic key event w/ left/right modifiers 1`] = `
"import { template as _template, children as _children, renderEffect as _renderEffect, withModifiers as _withModifiers, withKeys as _withKeys, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, renderEffect as _renderEffect, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_renderEffect(() => _on(n1, _ctx.e, _withKeys(_withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["left"]), ["left"]))) _renderEffect(() => {
_on(n1, _ctx.e, () => _ctx.test, undefined, {
modifiers: ["left"],
keys: ["left"]
})})
return n0 return n0
}" }"
`; `;
@ -373,35 +435,40 @@ const t0 = _template("<div></div><div></div><div></div>")
(() => { (() => {
const n0 = t0() const n0 = t0()
const { 0: [n1], 1: [n2], 2: [n3],} = _children(n0) const { 0: [n1], 1: [n2], 2: [n3],} = _children(n0)
_on(n1, "click", $event => (x.value=_unref(y))) _on(n1, "click", () => $event => (x.value=_unref(y)))
_on(n2, "click", $event => (x.value++)) _on(n2, "click", () => $event => (x.value++))
_on(n3, "click", $event => ({ x: x.value } = _unref(y))) _on(n3, "click", () => $event => ({ x: x.value } = _unref(y)))
return n0 return n0
})()" })()"
`; `;
exports[`v-on > should wrap keys guard for keyboard events or dynamic events 1`] = ` exports[`v-on > should wrap keys guard for keyboard events or dynamic events 1`] = `
"import { template as _template, children as _children, withModifiers as _withModifiers, withKeys as _withKeys, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "keydown", _withKeys(_withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop", "ctrl"]), ["a"]), { capture: true }) _on(n1, "keydown", () => _ctx.test, { capture: true }, {
modifiers: ["stop", "ctrl"],
keys: ["a"]
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should wrap keys guard for static key event w/ left/right modifiers 1`] = ` exports[`v-on > should wrap keys guard for static key event w/ left/right modifiers 1`] = `
"import { template as _template, children as _children, withKeys as _withKeys, on as _on } from 'vue/vapor'; "import { template as _template, children as _children, on as _on } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "keyup", _withKeys((...args) => (_ctx.test && _ctx.test(...args)), ["left"])) _on(n1, "keyup", () => _ctx.test, undefined, {
keys: ["left"]
})
return n0 return n0
}" }"
`; `;
@ -414,7 +481,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
const { 0: [n1],} = _children(n0) const { 0: [n1],} = _children(n0)
_on(n1, "click", (...args) => (_ctx.handleClick && _ctx.handleClick(...args))) _on(n1, "click", () => _ctx.handleClick)
return n0 return n0
}" }"
`; `;

View File

@ -167,7 +167,7 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains('_on(n1, "click", $event => (_ctx.i++))') expect(code).contains('_on(n1, "click", () => $event => (_ctx.i++))')
}) })
test('should wrap in unref if identifier is setup-maybe-ref w/ inline: true', () => { test('should wrap in unref if identifier is setup-maybe-ref w/ inline: true', () => {
@ -186,10 +186,12 @@ describe('v-on', () => {
expect(vaporHelpers).contains('unref') expect(vaporHelpers).contains('unref')
expect(helpers.size).toBe(0) expect(helpers.size).toBe(0)
expect(code).contains('_on(n1, "click", $event => (x.value=_unref(y)))')
expect(code).contains('_on(n2, "click", $event => (x.value++))')
expect(code).contains( expect(code).contains(
'_on(n3, "click", $event => ({ x: x.value } = _unref(y)))', '_on(n1, "click", () => $event => (x.value=_unref(y)))',
)
expect(code).contains('_on(n2, "click", () => $event => (x.value++))')
expect(code).contains(
'_on(n3, "click", () => $event => ({ x: x.value } = _unref(y)))',
) )
}) })
@ -207,7 +209,9 @@ describe('v-on', () => {
// should wrap with `{` for multiple statements // should wrap with `{` for multiple statements
// in this case the return value is discarded and the behavior is // in this case the return value is discarded and the behavior is
// consistent with 2.x // consistent with 2.x
expect(code).contains('_on(n1, "click", $event => {_ctx.foo();_ctx.bar()})') expect(code).contains(
'_on(n1, "click", () => $event => {_ctx.foo();_ctx.bar()})',
)
}) })
test('should handle multi-line statement', () => { test('should handle multi-line statement', () => {
@ -225,7 +229,7 @@ describe('v-on', () => {
// in this case the return value is discarded and the behavior is // in this case the return value is discarded and the behavior is
// consistent with 2.x // consistent with 2.x
expect(code).contains( expect(code).contains(
'_on(n1, "click", $event => {\n_ctx.foo();\n_ctx.bar()\n})', '_on(n1, "click", () => $event => {\n_ctx.foo();\n_ctx.bar()\n})',
) )
}) })
@ -243,7 +247,9 @@ describe('v-on', () => {
expect(code).matchSnapshot() expect(code).matchSnapshot()
// should NOT prefix $event // should NOT prefix $event
expect(code).contains('_on(n1, "click", $event => (_ctx.foo($event)))') expect(code).contains(
'_on(n1, "click", () => $event => (_ctx.foo($event)))',
)
}) })
test('multiple inline statements w/ prefixIdentifiers: true', () => { test('multiple inline statements w/ prefixIdentifiers: true', () => {
@ -261,7 +267,7 @@ describe('v-on', () => {
expect(code).matchSnapshot() expect(code).matchSnapshot()
// should NOT prefix $event // should NOT prefix $event
expect(code).contains( expect(code).contains(
'_on(n1, "click", $event => {_ctx.foo($event);_ctx.bar()})', '_on(n1, "click", () => $event => {_ctx.foo($event);_ctx.bar()})',
) )
}) })
@ -276,7 +282,7 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains('_on(n1, "click", $event => _ctx.foo($event))') expect(code).contains('_on(n1, "click", () => $event => _ctx.foo($event))')
}) })
test('should NOT wrap as function if expression is already function expression (with Typescript)', () => { test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
@ -293,7 +299,9 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains('_on(n1, "click", (e: any): any => _ctx.foo(e))') expect(code).contains(
'_on(n1, "click", () => (e: any): any => _ctx.foo(e))',
)
}) })
test('should NOT wrap as function if expression is already function expression (with newlines)', () => { test('should NOT wrap as function if expression is already function expression (with newlines)', () => {
@ -359,9 +367,7 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains( expect(code).contains(`_on(n1, "click", () => _ctx.a['b' + _ctx.c])`)
`_on(n1, "click", (...args) => (_ctx.a['b' + _ctx.c] && _ctx.a['b' + _ctx.c](...args)))`,
)
}) })
test('function expression w/ prefixIdentifiers: true', () => { test('function expression w/ prefixIdentifiers: true', () => {
@ -377,7 +383,7 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains('_on(n1, "click", e => _ctx.foo(e))') expect(code).contains('_on(n1, "click", () => e => _ctx.foo(e))')
}) })
test('should error if no expression AND no modifier', () => { test('should error if no expression AND no modifier', () => {
@ -463,8 +469,6 @@ describe('v-on', () => {
) )
expect(vaporHelpers).contains('on') expect(vaporHelpers).contains('on')
expect(vaporHelpers).contains('withModifiers')
expect(ir.operation).toMatchObject([ expect(ir.operation).toMatchObject([
{ {
type: IRNodeTypes.SET_EVENT, type: IRNodeTypes.SET_EVENT,
@ -483,8 +487,7 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains('_withModifiers') expect(code).contains('modifiers: ["stop", "prevent"]')
expect(code).contains('["stop", "prevent"]')
expect(code).contains('{ capture: true, once: true }') expect(code).contains('{ capture: true, once: true }')
}) })
@ -536,12 +539,11 @@ describe('v-on', () => {
]) ])
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains( expect(code).contains(`_on(n1, "click", () => _ctx.test, undefined`)
'_on(n1, "click", _withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["stop"]))', expect(code).contains(`modifiers: ["stop"]`)
)
expect(code).contains( expect(code).contains(`_on(n1, "keyup", () => _ctx.test, undefined`)
'_on(n1, "keyup", _withKeys((...args) => (_ctx.test && _ctx.test(...args)), ["enter"]))', expect(code).contains(`keys: ["enter"]`)
)
}) })
test('should wrap keys guard for keyboard events or dynamic events', () => { test('should wrap keys guard for keyboard events or dynamic events', () => {
@ -723,8 +725,6 @@ describe('v-on', () => {
}) })
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains( expect(code).contains(`_on(n1, "click", () => _ctx.foo.bar)`)
`_on(n1, "click", (...args) => (_ctx.foo.bar && _ctx.foo.bar(...args)))`,
)
}) })
}) })

View File

@ -1,5 +1,12 @@
import { isMemberExpression } from '@vue/compiler-dom' import { isMemberExpression } from '@vue/compiler-dom'
import { type CodeFragment, type CodegenContext, NEWLINE } from '../generate' import {
type CodeFragment,
type CodegenContext,
INDENT_END,
INDENT_START,
NEWLINE,
buildCodeFragment,
} from '../generate'
import type { SetEventIRNode } from '../ir' import type { SetEventIRNode } from '../ir'
import { genExpression } from './expression' import { genExpression } from './expression'
@ -15,13 +22,24 @@ export function genSetEvent(
const { keys, nonKeys, options } = oper.modifiers const { keys, nonKeys, options } = oper.modifiers
const name = genName() const name = genName()
const handler = genFinalizedHandler() const handler = genEventHandler()
const opt = const modifierOptions = genModifierOptions()
!!options.length && `{ ${options.map(v => `${v}: true`).join(', ')} }` const handlerOptions = options.length
? `{ ${options.map(v => `${v}: true`).join(', ')} }`
: modifierOptions
? 'undefined'
: undefined
return [ return [
NEWLINE, NEWLINE,
...call(vaporHelper('on'), `n${oper.element}`, name, handler, opt), ...call(
vaporHelper('on'),
`n${oper.element}`,
name,
handler,
handlerOptions,
modifierOptions,
),
] ]
function genName(): CodeFragment[] { function genName(): CodeFragment[] {
@ -42,55 +60,41 @@ export function genSetEvent(
if (exp && exp.content.trim()) { if (exp && exp.content.trim()) {
const isMemberExp = isMemberExpression(exp.content, ctxOptions) const isMemberExp = isMemberExpression(exp.content, ctxOptions)
const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content)) const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content))
const hasMultipleStatements = exp.content.includes(`;`)
if (isInlineStatement) { if (isInlineStatement) {
const expr = context.withId(() => genExpression(exp, context), { const expr = context.withId(() => genExpression(exp, context), {
$event: null, $event: null,
}) })
const hasMultipleStatements = exp.content.includes(`;`)
return [ return [
'$event => ', '() => $event => ',
hasMultipleStatements ? '{' : '(', hasMultipleStatements ? '{' : '(',
...expr, ...expr,
hasMultipleStatements ? '}' : ')', hasMultipleStatements ? '}' : ')',
] ]
} else { } else {
const expr = genExpression(exp, context) return ['() => ', ...genExpression(exp, context)]
if (isMemberExp) {
return ['(...args) => (', ...expr, ' && ', ...expr, '(...args))']
} else {
return expr
} }
} }
}
return '() => {}'
}
function genFinalizedHandler() { return ['() => {}']
let expr = genEventHandler() }
function genModifierOptions() {
const hasOptions = nonKeys.length || keys.length
if (!hasOptions) return
const [frag, push] = buildCodeFragment('{', INDENT_START)
if (nonKeys.length) { if (nonKeys.length) {
expr = [ push(NEWLINE, 'modifiers: ', genArrayExpression(nonKeys))
vaporHelper('withModifiers'), }
'(', if (keys.length && nonKeys.length) {
...expr, push(',')
', ',
genArrayExpression(nonKeys),
')',
]
} }
if (keys.length) { if (keys.length) {
expr = [ push(NEWLINE, 'keys: ', genArrayExpression(keys))
vaporHelper('withKeys'),
'(',
...expr,
', ',
genArrayExpression(keys),
')',
]
} }
push(INDENT_END, NEWLINE, '}')
return expr return frag
} }
} }

View File

@ -29,7 +29,7 @@ const createDemo = (defaultValue: boolean) =>
1: [n2], 1: [n2],
} = children(n0) } = children(n0)
withDirectives(n2, [[vShow, () => visible.value]]) withDirectives(n2, [[vShow, () => visible.value]])
on(n1 as HTMLElement, 'click', handleClick) on(n1 as HTMLElement, 'click', () => handleClick)
return n0 return n0
}, },
}) })

View File

@ -8,7 +8,7 @@ import {
} from '@vue/shared' } from '@vue/shared'
import type { ComponentInternalInstance } from '../component' import type { ComponentInternalInstance } from '../component'
import type { ObjectDirective } from '../directive' import type { ObjectDirective } from '../directive'
import { on } from '../dom/on' import { addEventListener } from '../dom/event'
import { nextTick } from '../scheduler' import { nextTick } from '../scheduler'
import { warn } from '../warning' import { warn } from '../warning'
@ -50,7 +50,7 @@ export const vModelText: ObjectDirective<
assignFnMap.set(el, assigner) assignFnMap.set(el, assigner)
const castToNumber = number // || (vnode.props && vnode.props.type === 'number') const castToNumber = number // || (vnode.props && vnode.props.type === 'number')
on(el, lazy ? 'change' : 'input', e => { addEventListener(el, lazy ? 'change' : 'input', e => {
if ((e.target as any).composing) return if ((e.target as any).composing) return
let domValue: string | number = el.value let domValue: string | number = el.value
if (trim) { if (trim) {
@ -62,18 +62,18 @@ export const vModelText: ObjectDirective<
assigner(domValue) assigner(domValue)
}) })
if (trim) { if (trim) {
on(el, 'change', () => { addEventListener(el, 'change', () => {
el.value = el.value.trim() el.value = el.value.trim()
}) })
} }
if (!lazy) { if (!lazy) {
on(el, 'compositionstart', onCompositionStart) addEventListener(el, 'compositionstart', onCompositionStart)
on(el, 'compositionend', onCompositionEnd) addEventListener(el, 'compositionend', onCompositionEnd)
// Safari < 10.2 & UIWebView doesn't fire compositionend when // Safari < 10.2 & UIWebView doesn't fire compositionend when
// switching focus before confirming composition choice // switching focus before confirming composition choice
// this also fixes the issue where some browsers e.g. iOS Chrome // this also fixes the issue where some browsers e.g. iOS Chrome
// fires "change" instead of "input" on autocomplete. // fires "change" instead of "input" on autocomplete.
on(el, 'change', onCompositionEnd) addEventListener(el, 'change', onCompositionEnd)
} }
}, },
// set value on mounted so it's after min/max for type="range" // set value on mounted so it's after min/max for type="range"
@ -122,7 +122,7 @@ export const vModelSelect: ObjectDirective<HTMLSelectElement, any, 'number'> = {
{ value, oldValue, instance, modifiers: { number = false } = {} }, { value, oldValue, instance, modifiers: { number = false } = {} },
) { ) {
const isSetModel = isSet(value) const isSetModel = isSet(value)
on(el, 'change', () => { addEventListener(el, 'change', () => {
const selectedVal = Array.prototype.filter const selectedVal = Array.prototype.filter
.call(el.options, (o: HTMLOptionElement) => o.selected) .call(el.options, (o: HTMLOptionElement) => o.selected)
.map((o: HTMLOptionElement) => .map((o: HTMLOptionElement) =>

View File

@ -1,9 +1,9 @@
import { isArray, toDisplayString } from '@vue/shared' import { isArray, toDisplayString } from '@vue/shared'
import type { Block, ParentBlock } from './render' import type { Block, ParentBlock } from './render'
export * from './dom/patchProp' export * from './dom/prop'
export * from './dom/event'
export * from './dom/templateRef' export * from './dom/templateRef'
export * from './dom/on'
export function normalizeBlock(block: Block): Node[] { export function normalizeBlock(block: Block): Node[] {
const nodes: Node[] = [] const nodes: Node[] = []

View File

@ -0,0 +1,55 @@
import {
getCurrentEffect,
getCurrentScope,
onEffectCleanup,
onScopeDispose,
} from '@vue/reactivity'
import { recordPropMetadata } from './prop'
import { toHandlerKey } from '@vue/shared'
import { withKeys, withModifiers } from '@vue/runtime-dom'
export function addEventListener(
el: HTMLElement,
event: string,
handler: (...args: any) => any,
options?: AddEventListenerOptions,
) {
el.addEventListener(event, handler, options)
return () => el.removeEventListener(event, handler, options)
}
export function on(
el: HTMLElement,
event: string,
handlerGetter: () => undefined | ((...args: any[]) => any),
options?: AddEventListenerOptions,
{ modifiers, keys }: { modifiers?: string[]; keys?: string[] } = {},
) {
recordPropMetadata(el, toHandlerKey(event), handlerGetter)
const cleanup = addEventListener(
el,
event,
(...args: any[]) => {
let handler = handlerGetter()
if (!handler) return
if (modifiers) {
handler = withModifiers(handler, modifiers)
}
if (keys) {
handler = withKeys(handler, keys)
}
handler && handler(...args)
},
options,
)
const scope = getCurrentScope()
const effect = getCurrentEffect()
if (effect && effect.scope === scope) {
onEffectCleanup(cleanup)
} else if (scope) {
onScopeDispose(cleanup)
}
}

View File

@ -1,28 +0,0 @@
import {
getCurrentEffect,
getCurrentScope,
onEffectCleanup,
onScopeDispose,
} from '@vue/reactivity'
import { recordPropMetadata } from './patchProp'
import { toHandlerKey } from '@vue/shared'
export function on(
el: HTMLElement,
event: string,
handler: (...args: any) => any,
options?: AddEventListenerOptions,
) {
recordPropMetadata(el, toHandlerKey(event), handler)
el.addEventListener(event, handler, options)
const scope = getCurrentScope()
const effect = getCurrentEffect()
const cleanup = () => el.removeEventListener(event, handler, options)
if (effect && effect.scope === scope) {
onEffectCleanup(cleanup)
} else if (scope) {
onScopeDispose(cleanup)
}
}

View File

@ -37,7 +37,6 @@ export {
getCurrentScope, getCurrentScope,
onScopeDispose, onScopeDispose,
} from '@vue/reactivity' } from '@vue/reactivity'
export { withModifiers, withKeys } from '@vue/runtime-dom'
export { nextTick } from './scheduler' export { nextTick } from './scheduler'
export { getCurrentInstance, type ComponentInternalInstance } from './component' export { getCurrentInstance, type ComponentInternalInstance } from './component'