refactor: merge delegate & modifier options of event

This commit is contained in:
三咲智子 Kevin Deng 2024-02-25 15:11:25 +08:00
parent ff943f4ddf
commit fb3e8ee8c0
No known key found for this signature in database
GPG Key ID: 69992F2250DFD93E
17 changed files with 362 additions and 266 deletions

View File

@ -146,13 +146,15 @@ export function render(_ctx) {
`; `;
exports[`compile > dynamic root nodes and interpolation 1`] = ` exports[`compile > dynamic root nodes and interpolation 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<button></button>") const t0 = _template("<button></button>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleClick)) _on(n0, "click", () => _ctx.handleClick, {
delegate: true
})
_renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count)) _renderEffect(() => _setText(n0, _ctx.count, "foo", _ctx.count, "foo", _ctx.count))
_renderEffect(() => _setDynamicProp(n0, "id", _ctx.count)) _renderEffect(() => _setDynamicProp(n0, "id", _ctx.count))
return n0 return n0

View File

@ -1,14 +1,16 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`compiler: v-for > basic v-for 1`] = ` exports[`compiler: v-for > basic v-for 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = _createFor(() => (_ctx.items), (_block) => { const n0 = _createFor(() => (_ctx.items), (_block) => {
const n2 = t0() const n2 = t0()
_recordMetadata(n2, "events", "click", _eventHandler(() => $event => (_ctx.remove(_block.s[0])))) _on(n2, "click", () => $event => (_ctx.remove(_block.s[0])), {
delegate: true
})
const _updateEffect = () => { const _updateEffect = () => {
const [item] = _block.s const [item] = _block.s
_setText(n2, item) _setText(n2, item)

View File

@ -1,13 +1,15 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`v-on > complex member expression w/ prefixIdentifiers: true 1`] = ` exports[`v-on > complex member expression w/ prefixIdentifiers: true 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c])) _on(n0, "click", () => _ctx.a['b' + _ctx.c], {
delegate: true
})
return n0 return n0
}" }"
`; `;
@ -46,7 +48,7 @@ export function render(_ctx) {
`; `;
exports[`v-on > event modifier 1`] = ` exports[`v-on > event modifier 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<a></a>") const t0 = _template("<a></a>")
const t1 = _template("<form></form>") const t1 = _template("<form></form>")
const t2 = _template("<div></div>") const t2 = _template("<div></div>")
@ -76,249 +78,300 @@ export function render(_ctx) {
const n19 = t3() const n19 = t3()
const n20 = t3() const n20 = t3()
const n21 = t3() const n21 = t3()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleEvent, { _on(n0, "click", () => _ctx.handleEvent, {
modifiers: ["stop"] modifiers: ["stop"],
})) delegate: true
_on(n1, "submit", () => _ctx.handleEvent, undefined, { })
_on(n1, "submit", () => _ctx.handleEvent, {
modifiers: ["prevent"] modifiers: ["prevent"]
}) })
_recordMetadata(n2, "events", "click", _eventHandler(() => _ctx.handleEvent, { _on(n2, "click", () => _ctx.handleEvent, {
modifiers: ["stop", "prevent"] modifiers: ["stop", "prevent"],
})) delegate: true
_recordMetadata(n3, "events", "click", _eventHandler(() => _ctx.handleEvent, { })
modifiers: ["self"] _on(n3, "click", () => _ctx.handleEvent, {
}))
_on(n4, "click", () => _ctx.handleEvent, { capture: true })
_on(n5, "click", () => _ctx.handleEvent, { once: true })
_on(n6, "scroll", () => _ctx.handleEvent, { passive: true })
_recordMetadata(n7, "events", "contextmenu", _eventHandler(() => _ctx.handleEvent, {
modifiers: ["right"]
}))
_recordMetadata(n8, "events", "click", _eventHandler(() => _ctx.handleEvent, {
modifiers: ["left"]
}))
_recordMetadata(n9, "events", "mouseup", _eventHandler(() => _ctx.handleEvent, {
modifiers: ["middle"]
}))
_recordMetadata(n10, "events", "contextmenu", _eventHandler(() => _ctx.handleEvent, {
modifiers: ["right"]
}))
_recordMetadata(n11, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["enter"]
}))
_recordMetadata(n12, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["tab"]
}))
_recordMetadata(n13, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["delete"]
}))
_recordMetadata(n14, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["esc"]
}))
_recordMetadata(n15, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["space"]
}))
_recordMetadata(n16, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["up"]
}))
_recordMetadata(n17, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["down"]
}))
_recordMetadata(n18, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
keys: ["left"]
}))
_recordMetadata(n19, "events", "keyup", _eventHandler(() => _ctx.submit, {
modifiers: ["middle"]
}))
_recordMetadata(n20, "events", "keyup", _eventHandler(() => _ctx.submit, {
modifiers: ["middle", "self"]
}))
_recordMetadata(n21, "events", "keyup", _eventHandler(() => _ctx.handleEvent, {
modifiers: ["self"], modifiers: ["self"],
keys: ["enter"] delegate: true
})) })
_on(n4, "click", () => _ctx.handleEvent, {
capture: true
})
_on(n5, "click", () => _ctx.handleEvent, {
once: true
})
_on(n6, "scroll", () => _ctx.handleEvent, {
passive: true
})
_on(n7, "contextmenu", () => _ctx.handleEvent, {
modifiers: ["right"],
delegate: true
})
_on(n8, "click", () => _ctx.handleEvent, {
modifiers: ["left"],
delegate: true
})
_on(n9, "mouseup", () => _ctx.handleEvent, {
modifiers: ["middle"],
delegate: true
})
_on(n10, "contextmenu", () => _ctx.handleEvent, {
modifiers: ["right"],
delegate: true
})
_on(n11, "keyup", () => _ctx.handleEvent, {
keys: ["enter"],
delegate: true
})
_on(n12, "keyup", () => _ctx.handleEvent, {
keys: ["tab"],
delegate: true
})
_on(n13, "keyup", () => _ctx.handleEvent, {
keys: ["delete"],
delegate: true
})
_on(n14, "keyup", () => _ctx.handleEvent, {
keys: ["esc"],
delegate: true
})
_on(n15, "keyup", () => _ctx.handleEvent, {
keys: ["space"],
delegate: true
})
_on(n16, "keyup", () => _ctx.handleEvent, {
keys: ["up"],
delegate: true
})
_on(n17, "keyup", () => _ctx.handleEvent, {
keys: ["down"],
delegate: true
})
_on(n18, "keyup", () => _ctx.handleEvent, {
keys: ["left"],
delegate: true
})
_on(n19, "keyup", () => _ctx.submit, {
modifiers: ["middle"],
delegate: true
})
_on(n20, "keyup", () => _ctx.submit, {
modifiers: ["middle", "self"],
delegate: true
})
_on(n21, "keyup", () => _ctx.handleEvent, {
modifiers: ["self"],
keys: ["enter"],
delegate: true
})
return [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20, n21] return [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20, n21]
}" }"
`; `;
exports[`v-on > function expression w/ prefixIdentifiers: true 1`] = ` exports[`v-on > function expression w/ prefixIdentifiers: true 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => e => _ctx.foo(e))) _on(n0, "click", () => e => _ctx.foo(e), {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > inline statement w/ prefixIdentifiers: true 1`] = ` exports[`v-on > inline statement w/ prefixIdentifiers: true 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.foo($event)))) _on(n0, "click", () => $event => (_ctx.foo($event)), {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > multiple inline statements w/ prefixIdentifiers: true 1`] = ` exports[`v-on > multiple inline statements w/ prefixIdentifiers: true 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo($event);_ctx.bar()})) _on(n0, "click", () => $event => {_ctx.foo($event);_ctx.bar()}, {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should NOT add a prefix to $event if the expression is a function expression 1`] = ` exports[`v-on > should NOT add a prefix to $event if the expression is a function expression 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.i++;_ctx.foo($event)})) _on(n0, "click", () => $event => {_ctx.i++;_ctx.foo($event)}, {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should NOT wrap as function if expression is already function expression (with Typescript) 1`] = ` exports[`v-on > should NOT wrap as function if expression is already function expression (with Typescript) 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => (e: any): any => _ctx.foo(e))) _on(n0, "click", () => (e: any): any => _ctx.foo(e), {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should NOT wrap as function if expression is already function expression (with newlines) 1`] = ` exports[`v-on > should NOT wrap as function if expression is already function expression (with newlines) 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _on(n0, "click", () =>
$event => { $event => {
_ctx.foo($event) _ctx.foo($event)
} }
)) , {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should NOT wrap as function if expression is already function expression 1`] = ` exports[`v-on > should NOT wrap as function if expression is already function expression 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => _ctx.foo($event))) _on(n0, "click", () => $event => _ctx.foo($event), {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should NOT wrap as function if expression is complex member expression 1`] = ` exports[`v-on > should NOT wrap as function if expression is complex member expression 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c])) _on(n0, "click", () => _ctx.a['b' + _ctx.c], {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should delegate event 1`] = ` exports[`v-on > should delegate event 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test)) _on(n0, "click", () => _ctx.test, {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should handle multi-line statement 1`] = ` exports[`v-on > should handle multi-line statement 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => { _on(n0, "click", () => $event => {
_ctx.foo(); _ctx.foo();
_ctx.bar() _ctx.bar()
})) }, {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should handle multiple inline statement 1`] = ` exports[`v-on > should handle multiple inline statement 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo();_ctx.bar()})) _on(n0, "click", () => $event => {_ctx.foo();_ctx.bar()}, {
delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > should not prefix member expression 1`] = ` exports[`v-on > should not prefix member expression 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.foo.bar)) _on(n0, "click", () => _ctx.foo.bar, {
delegate: true
})
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 { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("keyup") _delegateEvents("keyup")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, { _on(n0, "keyup", () => _ctx.test, {
modifiers: ["exact"] modifiers: ["exact"],
})) delegate: true
})
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 { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click", "keyup") _delegateEvents("click", "keyup")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test, { _on(n0, "click", () => _ctx.test, {
modifiers: ["stop"] modifiers: ["stop"],
})) delegate: true
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, { })
keys: ["enter"] _on(n0, "keyup", () => _ctx.test, {
})) keys: ["enter"],
delegate: true
})
return n0 return n0
}" }"
`; `;
@ -329,23 +382,26 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_on(n0, "click", () => _ctx.test, { capture: true, once: true }, { _on(n0, "click", () => _ctx.test, {
modifiers: ["stop", "prevent"] modifiers: ["stop", "prevent"],
capture: true,
once: true
}) })
return n0 return n0
}" }"
`; `;
exports[`v-on > should transform click.middle 1`] = ` exports[`v-on > should transform click.middle 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("mouseup") _delegateEvents("mouseup")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "mouseup", _eventHandler(() => _ctx.test, { _on(n0, "mouseup", () => _ctx.test, {
modifiers: ["middle"] modifiers: ["middle"],
})) delegate: true
})
return n0 return n0
}" }"
`; `;
@ -357,7 +413,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_renderEffect(() => { _renderEffect(() => {
_on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _ctx.test, undefined, { _on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _ctx.test, {
modifiers: ["middle"] modifiers: ["middle"]
}) })
}) })
@ -366,15 +422,16 @@ export function render(_ctx) {
`; `;
exports[`v-on > should transform click.right 1`] = ` exports[`v-on > should transform click.right 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("contextmenu") _delegateEvents("contextmenu")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "contextmenu", _eventHandler(() => _ctx.test, { _on(n0, "contextmenu", () => _ctx.test, {
modifiers: ["right"] modifiers: ["right"],
})) delegate: true
})
return n0 return n0
}" }"
`; `;
@ -386,7 +443,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_renderEffect(() => { _renderEffect(() => {
_on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _ctx.test, undefined, { _on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _ctx.test, {
modifiers: ["right"], modifiers: ["right"],
keys: ["right"] keys: ["right"]
}) })
@ -396,13 +453,15 @@ export function render(_ctx) {
`; `;
exports[`v-on > should wrap as function if expression is inline statement 1`] = ` exports[`v-on > should wrap as function if expression is inline statement 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.i++))) _on(n0, "click", () => $event => (_ctx.i++), {
delegate: true
})
return n0 return n0
}" }"
`; `;
@ -414,7 +473,7 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_renderEffect(() => { _renderEffect(() => {
_on(n0, _ctx.e, () => _ctx.test, undefined, { _on(n0, _ctx.e, () => _ctx.test, {
modifiers: ["left"], modifiers: ["left"],
keys: ["left"] keys: ["left"]
}) })
@ -428,9 +487,15 @@ exports[`v-on > should wrap in unref if identifier is setup-maybe-ref w/ inline:
const n0 = t0() const n0 = t0()
const n1 = t0() const n1 = t0()
const n2 = t0() const n2 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (x.value=_unref(y)))) _on(n0, "click", () => $event => (x.value=_unref(y)), {
_recordMetadata(n1, "events", "click", _eventHandler(() => $event => (x.value++))) delegate: true
_recordMetadata(n2, "events", "click", _eventHandler(() => $event => ({ x: x.value } = _unref(y)))) })
_on(n1, "click", () => $event => (x.value++), {
delegate: true
})
_on(n2, "click", () => $event => ({ x: x.value } = _unref(y)), {
delegate: true
})
return [n0, n1, n2] return [n0, n1, n2]
})()" })()"
`; `;
@ -441,36 +506,40 @@ const t0 = _template("<div></div>")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_on(n0, "keydown", () => _ctx.test, { capture: true }, { _on(n0, "keydown", () => _ctx.test, {
modifiers: ["stop", "ctrl"], modifiers: ["stop", "ctrl"],
keys: ["a"] keys: ["a"],
capture: true
}) })
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 { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("keyup") _delegateEvents("keyup")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, { _on(n0, "keyup", () => _ctx.test, {
keys: ["left"] keys: ["left"],
})) delegate: true
})
return n0 return n0
}" }"
`; `;
exports[`v-on > simple expression 1`] = ` exports[`v-on > simple expression 1`] = `
"import { recordMetadata as _recordMetadata, eventHandler as _eventHandler, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor'; "import { on as _on, delegateEvents as _delegateEvents, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>") const t0 = _template("<div></div>")
_delegateEvents("click") _delegateEvents("click")
export function render(_ctx) { export function render(_ctx) {
const n0 = t0() const n0 = t0()
_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.handleClick)) _on(n0, "click", () => _ctx.handleClick, {
delegate: true
})
return n0 return n0
}" }"
`; `;

View File

@ -26,7 +26,7 @@ describe('v-on', () => {
) )
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(vaporHelpers).not.contains('on') expect(vaporHelpers).contains('on')
expect(helpers.size).toBe(0) expect(helpers.size).toBe(0)
expect(ir.block.effect).toEqual([]) expect(ir.block.effect).toEqual([])
expect(ir.block.operation).toMatchObject([ expect(ir.block.operation).toMatchObject([
@ -155,7 +155,7 @@ describe('v-on', () => {
compileWithVOn(`<div @click="i++"/>`) compileWithVOn(`<div @click="i++"/>`)
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(vaporHelpers).not.contains('on') expect(vaporHelpers).contains('on')
expect(helpers.size).toBe(0) expect(helpers.size).toBe(0)
expect(ir.block.effect).toEqual([]) expect(ir.block.effect).toEqual([])
expect(ir.block.operation).toMatchObject([ expect(ir.block.operation).toMatchObject([
@ -171,7 +171,9 @@ describe('v-on', () => {
}, },
]) ])
expect(code).contains( expect(code).contains(
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.i++)))', `_on(n0, "click", () => $event => (_ctx.i++), {
delegate: true
})`,
) )
}) })
@ -188,18 +190,19 @@ describe('v-on', () => {
}, },
) )
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(vaporHelpers).contains('unref') expect(vaporHelpers).contains('unref')
expect(helpers.size).toBe(0) expect(helpers.size).toBe(0)
expect(code).contains( expect(code)
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (x.value=_unref(y))))', .contains(`_on(n0, "click", () => $event => (x.value=_unref(y)), {
) delegate: true
expect(code).contains( })`)
'_recordMetadata(n1, "events", "click", _eventHandler(() => $event => (x.value++)))', expect(code).contains(`_on(n1, "click", () => $event => (x.value++), {
) delegate: true
expect(code).contains( })`)
'_recordMetadata(n2, "events", "click", _eventHandler(() => $event => ({ x: x.value } = _unref(y))))', expect(code)
) .contains(`_on(n2, "click", () => $event => ({ x: x.value } = _unref(y)), {
delegate: true
})`)
}) })
test('should handle multiple inline statement', () => { test('should handle multiple inline statement', () => {
@ -216,7 +219,9 @@ 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(
`_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo();_ctx.bar()}))`, `_on(n0, "click", () => $event => {_ctx.foo();_ctx.bar()}, {
delegate: true
})`,
) )
}) })
@ -234,7 +239,12 @@ 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(
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {\n_ctx.foo();\n_ctx.bar()\n})', `_on(n0, "click", () => $event => {
_ctx.foo();
_ctx.bar()
}, {
delegate: true
})`,
) )
}) })
@ -252,7 +262,9 @@ describe('v-on', () => {
]) ])
// should NOT prefix $event // should NOT prefix $event
expect(code).contains( expect(code).contains(
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => (_ctx.foo($event))))', `_on(n0, "click", () => $event => (_ctx.foo($event)), {
delegate: true
})`,
) )
}) })
@ -270,7 +282,9 @@ describe('v-on', () => {
]) ])
// should NOT prefix $event // should NOT prefix $event
expect(code).contains( expect(code).contains(
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => {_ctx.foo($event);_ctx.bar()}))', `_on(n0, "click", () => $event => {_ctx.foo($event);_ctx.bar()}, {
delegate: true
})`,
) )
}) })
@ -285,7 +299,9 @@ describe('v-on', () => {
}, },
]) ])
expect(code).contains( expect(code).contains(
'_recordMetadata(n0, "events", "click", _eventHandler(() => $event => _ctx.foo($event)))', `_on(n0, "click", () => $event => _ctx.foo($event), {
delegate: true
})`,
) )
}) })
@ -303,7 +319,9 @@ describe('v-on', () => {
}, },
]) ])
expect(code).contains( expect(code).contains(
'_recordMetadata(n0, "events", "click", _eventHandler(() => (e: any): any => _ctx.foo(e)))', `_on(n0, "click", () => (e: any): any => _ctx.foo(e), {
delegate: true
})`,
) )
}) })
@ -370,7 +388,9 @@ describe('v-on', () => {
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains( expect(code).contains(
`_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.a['b' + _ctx.c]))`, `_on(n0, "click", () => _ctx.a['b' + _ctx.c], {
delegate: true
})`,
) )
}) })
@ -387,7 +407,9 @@ describe('v-on', () => {
}, },
]) ])
expect(code).contains( expect(code).contains(
'_recordMetadata(n0, "events", "click", _eventHandler(() => e => _ctx.foo(e)))', `_on(n0, "click", () => e => _ctx.foo(e), {
delegate: true
})`,
) )
}) })
@ -443,9 +465,12 @@ describe('v-on', () => {
}, },
]) ])
expect(code).contains( expect(code).contains(
'_on(n0, "click", () => _ctx.test, { capture: true, once: true }, {', `_on(n0, "click", () => _ctx.test, {
modifiers: ["stop", "prevent"],
capture: true,
once: true
})`,
) )
expect(code).contains('modifiers: ["stop", "prevent"]')
}) })
test('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => { test('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => {
@ -497,14 +522,16 @@ describe('v-on', () => {
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains( expect(code).contains(
`_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.test, {`, `_on(n0, "click", () => _ctx.test, {
modifiers: ["stop"],
delegate: true
})`,
) )
expect(code).contains(`modifiers: ["stop"]`)
expect(code).contains( expect(code).contains(`_on(n0, "keyup", () => _ctx.test, {
`_recordMetadata(n0, "events", "keyup", _eventHandler(() => _ctx.test, {`, keys: ["enter"],
) delegate: true
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', () => {
@ -686,9 +713,8 @@ describe('v-on', () => {
}) })
expect(code).matchSnapshot() expect(code).matchSnapshot()
expect(code).contains( expect(code).contains(`_on(n0, "click", () => _ctx.foo.bar, {`)
`_recordMetadata(n0, "events", "click", _eventHandler(() => _ctx.foo.bar))`, expect(code).contains(`delegate: true`)
)
}) })
test('should delegate event', () => { test('should delegate event', () => {

View File

@ -7,78 +7,49 @@ import {
INDENT_END, INDENT_END,
INDENT_START, INDENT_START,
NEWLINE, NEWLINE,
buildCodeFragment,
genCall, genCall,
genMulti,
} from './utils' } from './utils'
export function genSetEvent( export function genSetEvent(
oper: SetEventIRNode, oper: SetEventIRNode,
context: CodegenContext, context: CodegenContext,
): CodeFragment[] { ): CodeFragment[] {
const { vaporHelper, options: ctxOptions } = context const { vaporHelper, options } = context
const { keys, nonKeys, options } = oper.modifiers const { element, key, keyOverride, value, modifiers, delegate } = oper
const name = genName() const name = genName()
const handler = genEventHandler() const handler = genEventHandler()
const modifierOptions = genModifierOptions() const eventOptions = genEventOptions()
if (oper.delegate) {
// oper.key is static
context.delegates.add(oper.key.content)
return [
NEWLINE,
...genCall(
vaporHelper('recordMetadata'),
`n${oper.element}`,
'"events"',
name,
genCall(vaporHelper('eventHandler'), handler, modifierOptions),
),
]
}
const handlerOptions = options.length
? `{ ${options.map(v => `${v}: true`).join(', ')} }`
: modifierOptions
? 'undefined'
: undefined
return [ return [
NEWLINE, NEWLINE,
...genCall( ...genCall(vaporHelper('on'), `n${element}`, name, handler, eventOptions),
vaporHelper('on'),
`n${oper.element}`,
name,
handler,
handlerOptions,
modifierOptions,
),
] ]
function genName(): CodeFragment[] { function genName(): CodeFragment[] {
const expr = genExpression(oper.key, context) const expr = genExpression(key, context)
if (oper.keyOverride) { if (keyOverride) {
// TODO unit test // TODO unit test
const find = JSON.stringify(oper.keyOverride[0]) const find = JSON.stringify(keyOverride[0])
const replacement = JSON.stringify(oper.keyOverride[1]) const replacement = JSON.stringify(keyOverride[1])
const wrapped: CodeFragment[] = ['(', ...expr, ')'] const wrapped: CodeFragment[] = ['(', ...expr, ')']
return [...wrapped, ` === ${find} ? ${replacement} : `, ...wrapped] return [...wrapped, ` === ${find} ? ${replacement} : `, ...wrapped]
} else { } else {
return genExpression(oper.key, context) return genExpression(key, context)
} }
} }
function genEventHandler() { function genEventHandler() {
const exp = oper.value if (value && value.content.trim()) {
if (exp && exp.content.trim()) { const isMemberExp = isMemberExpression(value.content, options)
const isMemberExp = isMemberExpression(exp.content, ctxOptions) const isInlineStatement = !(isMemberExp || fnExpRE.test(value.content))
const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content))
if (isInlineStatement) { if (isInlineStatement) {
const expr = context.withId(() => genExpression(exp, context), { const expr = context.withId(() => genExpression(value, context), {
$event: null, $event: null,
}) })
const hasMultipleStatements = exp.content.includes(`;`) const hasMultipleStatements = value.content.includes(`;`)
return [ return [
'() => $event => ', '() => $event => ',
hasMultipleStatements ? '{' : '(', hasMultipleStatements ? '{' : '(',
@ -86,28 +57,33 @@ export function genSetEvent(
hasMultipleStatements ? '}' : ')', hasMultipleStatements ? '}' : ')',
] ]
} else { } else {
return ['() => ', ...genExpression(exp, context)] return ['() => ', ...genExpression(value, context)]
} }
} }
return ['() => {}'] return ['() => {}']
} }
function genModifierOptions() { function genEventOptions(): CodeFragment[] | undefined {
const hasOptions = nonKeys.length || keys.length let { options, keys, nonKeys } = modifiers
if (!hasOptions) return
const [frag, push] = buildCodeFragment('{', INDENT_START) if (delegate) {
if (nonKeys.length) { // key is static
push(NEWLINE, 'modifiers: ', genArrayExpression(nonKeys)) context.delegates.add(key.content)
options = [...options, 'delegate']
} }
if (keys.length && nonKeys.length) { if (!options.length && !nonKeys.length && !keys.length) return
push(',')
} return genMulti(
if (keys.length) { [
push(NEWLINE, 'keys: ', genArrayExpression(keys)) ['{', INDENT_START, NEWLINE],
} [INDENT_END, NEWLINE, '}'],
push(INDENT_END, NEWLINE, '}') [', ', NEWLINE],
return frag ],
!!nonKeys.length && ['modifiers: ', genArrayExpression(nonKeys)],
!!keys.length && ['keys: ', genArrayExpression(keys)],
...options.map((option): CodeFragment[] => [`${option}: true`]),
)
} }
} }

View File

@ -32,24 +32,28 @@ export function buildCodeFragment(...frag: CodeFragment[]) {
export function genMulti( export function genMulti(
[left, right, seg]: [ [left, right, seg]: [
left: CodeFragment, left: CodeFragments,
right: CodeFragment, right: CodeFragments,
segment: CodeFragment, segment: CodeFragments,
], ],
...fns: CodeFragments[] ...fns: CodeFragments[]
): CodeFragment[] { ): CodeFragment[] {
const frag: CodeFragment[] = [] const frag: CodeFragment[] = []
fns = fns.filter(Boolean) fns = fns.filter(Boolean)
frag.push(left) push(left)
for (let [i, fn] of ( for (let [i, fn] of (
fns as Array<Exclude<CodeFragments, FalsyValue>> fns as Array<Exclude<CodeFragments, FalsyValue>>
).entries()) { ).entries()) {
push(fn)
if (i < fns.length - 1) push(seg)
}
push(right)
return frag
function push(fn: CodeFragments) {
if (!isArray(fn)) fn = [fn] if (!isArray(fn)) fn = [fn]
frag.push(...fn) frag.push(...fn)
if (i < fns.length - 1) frag.push(seg)
} }
frag.push(right)
return frag
} }
export function genCall( export function genCall(

View File

@ -1,4 +1,4 @@
import { append, insert, normalizeBlock, prepend, remove } from '../src/dom' import { append, insert, normalizeBlock, prepend, remove } from '../src/dom/dom'
import { fragmentKey } from '../src/render' import { fragmentKey } from '../src/render'
const node1 = document.createTextNode('node1') const node1 = document.createTextNode('node1')

View File

@ -1,6 +1,5 @@
import { NOOP } from '@vue/shared' import { NOOP } from '@vue/shared'
import { import {
setDynamicProp as _setDynamicProp,
setAttr, setAttr,
setClass, setClass,
setDOMProp, setDOMProp,
@ -9,6 +8,7 @@ import {
setStyle, setStyle,
setText, setText,
} from '../../src' } from '../../src'
import { setDynamicProp as _setDynamicProp } from '../../src/dom/prop'
import { import {
createComponentInstance, createComponentInstance,
setCurrentInstance, setCurrentInstance,

View File

@ -1,10 +1,5 @@
import { isArray, toDisplayString } from '@vue/shared' import { isArray, toDisplayString } from '@vue/shared'
import type { Block } from './render' import type { Block } from '../render'
export * from './dom/style'
export * from './dom/prop'
export * from './dom/event'
export * from './dom/templateRef'
/*! #__NO_SIDE_EFFECTS__ */ /*! #__NO_SIDE_EFFECTS__ */
export function normalizeBlock(block: Block): Node[] { export function normalizeBlock(block: Block): Node[] {

View File

@ -22,17 +22,27 @@ interface ModifierOptions {
keys?: string[] keys?: string[]
} }
interface EventOptions extends AddEventListenerOptions, ModifierOptions {
delegate?: boolean
}
export type DelegatedHandler = {
(...args: any[]): any
delegate?: boolean
}
export function on( export function on(
el: HTMLElement, el: HTMLElement,
event: string, event: string,
handlerGetter: () => undefined | ((...args: any[]) => any), handlerGetter: () => undefined | ((...args: any[]) => any),
options?: AddEventListenerOptions, options: EventOptions = {},
modifierOptions?: ModifierOptions,
) { ) {
const handler = eventHandler(handlerGetter, modifierOptions) const handler: DelegatedHandler = eventHandler(handlerGetter, options)
handler.delegate = options.delegate
recordMetadata(el, 'events', event, handler) recordMetadata(el, 'events', event, handler)
const cleanup = addEventListener(el, event, handler, options)
if (!options.delegate) {
const cleanup = addEventListener(el, event, handler, options)
const scope = getCurrentScope() const scope = getCurrentScope()
const effect = getCurrentEffect() const effect = getCurrentEffect()
@ -41,9 +51,10 @@ export function on(
} else if (scope) { } else if (scope) {
onScopeDispose(cleanup) onScopeDispose(cleanup)
} }
}
} }
export function eventHandler( function eventHandler(
getter: () => undefined | ((...args: any[]) => any), getter: () => undefined | ((...args: any[]) => any),
{ modifiers, keys }: ModifierOptions = {}, { modifiers, keys }: ModifierOptions = {},
) { ) {
@ -51,12 +62,8 @@ export function eventHandler(
let handler = getter() let handler = getter()
if (!handler) return if (!handler) return
if (modifiers) { if (modifiers) handler = withModifiers(handler, modifiers)
handler = withModifiers(handler, modifiers) if (keys) handler = withKeys(handler, keys)
}
if (keys) {
handler = withKeys(handler, keys)
}
handler && handler(...args) handler && handler(...args)
} }
} }
@ -92,8 +99,8 @@ const delegatedEventHandler = (e: Event) => {
}, },
}) })
while (node !== null) { while (node !== null) {
const handler = getMetadata(node).events[e.type] as (...args: any[]) => any const handler = getMetadata(node).events[e.type]
if (handler && !node.disabled) { if (handler && handler.delegate && !node.disabled) {
handler(e) handler(e)
if (e.cancelBubble) return if (e.cancelBubble) return
} }

View File

@ -1,6 +1,6 @@
import { type EffectScope, effectScope, isReactive } from '@vue/reactivity' import { type EffectScope, effectScope, isReactive } from '@vue/reactivity'
import { isArray } from '@vue/shared' import { isArray } from '@vue/shared'
import { createComment, createTextNode, insert, remove } from './dom' import { createComment, createTextNode, insert, remove } from './dom/dom'
import { renderEffect } from './renderWatch' import { renderEffect } from './renderWatch'
import { type Block, type Fragment, fragmentKey } from './render' import { type Block, type Fragment, fragmentKey } from './render'

View File

@ -1,7 +1,7 @@
import { renderWatch } from './renderWatch' import { renderWatch } from './renderWatch'
import { type Block, type Fragment, fragmentKey } from './render' import { type Block, type Fragment, fragmentKey } from './render'
import { type EffectScope, effectScope } from '@vue/reactivity' import { type EffectScope, effectScope } from '@vue/reactivity'
import { createComment, createTextNode, insert, remove } from './dom' import { createComment, createTextNode, insert, remove } from './dom/dom'
type BlockFn = () => Block type BlockFn = () => Block

View File

@ -52,12 +52,25 @@ export * from './renderWatch'
export * from './template' export * from './template'
export * from './apiWatch' export * from './apiWatch'
export * from './directive' export * from './directive'
export * from './dom'
export { insert, prepend, append, remove, createTextNode } from './dom/dom'
export { setStyle } from './dom/style'
export {
setText,
setHtml,
setClass,
setAttr,
setDOMProp,
setDynamicProp,
setDynamicProps,
} from './dom/prop'
export { on, delegateEvents } from './dom/event'
export { setRef } from './dom/templateRef'
export * from './apiLifecycle' export * from './apiLifecycle'
export * from './if' export * from './if'
export * from './for' export * from './for'
export { defineComponent } from './apiDefineComponent' export { defineComponent } from './apiDefineComponent'
export { recordMetadata } from './metadata'
export * from './directives/vShow' export * from './directives/vShow'
export * from './directives/vModel' export * from './directives/vModel'

View File

@ -1,8 +1,9 @@
import type { Data } from '@vue/shared' import type { Data } from '@vue/shared'
import type { DelegatedHandler } from './dom/event'
export interface ElementMetadata { export interface ElementMetadata {
props: Data props: Data
events: Data events: Record<string, DelegatedHandler>
} }
export function getMetadata( export function getMetadata(

View File

@ -15,7 +15,7 @@ import {
} from './component' } from './component'
import { initProps } from './componentProps' import { initProps } from './componentProps'
import { invokeDirectiveHook } from './directive' import { invokeDirectiveHook } from './directive'
import { insert, querySelector, remove } from './dom' import { insert, querySelector, remove } from './dom/dom'
import { queuePostRenderEffect } from './scheduler' import { queuePostRenderEffect } from './scheduler'
export const fragmentKey = Symbol(__DEV__ ? `fragmentKey` : ``) export const fragmentKey = Symbol(__DEV__ ? `fragmentKey` : ``)

View File

@ -13,7 +13,8 @@ const remaining = computed(() => {
return tasks.value.filter(task => !task.completed).length return tasks.value.filter(task => !task.completed).length
}) })
function handleAdd() { function handleAdd(evt: MouseEvent) {
console.log(evt)
tasks.value.push({ tasks.value.push({
title: value.value, title: value.value,
completed: false, completed: false,
@ -67,7 +68,7 @@ function handleRemove(idx: number, task: Task) {
@keydown.enter="handleAdd" @keydown.enter="handleAdd"
placeholder="What need to be done?" placeholder="What need to be done?"
/> />
<button @click="handleAdd">Add</button> <button @click.passive="handleAdd">Add</button>
<button @click="handleClearComplete">Clear completed</button> <button @click="handleClearComplete">Clear completed</button>
<button @click="handleClearAll">Clear all</button> <button @click="handleClearAll">Clear all</button>
</div> </div>

View File

@ -48,7 +48,7 @@ export default defineComponent({
on(input, 'input', () => e => { on(input, 'input', () => e => {
value.value = e.target.value value.value = e.target.value
}) })
on(input, 'keydown', () => handleAdd, undefined, { on(input, 'keydown', () => handleAdd, {
keys: ['enter'], keys: ['enter'],
}) })