Events
A .vue template binds a listener the usual way — @click, @mousedown, and so on. Every listener receives one shared event object: type (the event's name), target/currentTarget, the propagation methods below, and whatever fields that event carries.
target and currentTarget are both the id of the node currently receiving the event — they're always equal, since there's no way yet to learn which descendant an event actually started on (no event delegation).
<template>
<div @mousedown="onMouseDown">Click and hold</div>
</template>NOTE
These are the only event names wired to real input. Binding any other name is accepted but never fires.
Pointer
click
Fires on a mousedown followed by a mouseup on the same node, before the mouseup listeners run — or after Enter/Space while the node is focused. Carries no fields of its own.
mousedown / mouseup / mousemove
A subset of the DOM's MouseEvent's fields:
clientX/clientY— pointer positionpageX/pageY— identical toclientX/clientY; nothing here scrolls the page itself, which is the only thing that would tell them apartmovementX/movementY— delta from whichever mouse/wheel event fired last;0for the first one. Amousemoveand themouseenter/mouseleavefrom the same pointer move report the same deltabutton— 0 for a move, which isn't about any one buttonbuttons— every button currently held, as a bitmaskdetail— how many clicks this is part of; 0 for a movectrlKey/shiftKey/altKey/metaKey— modifier keys held
mouseenter / mouseleave
Same fields as mousedown, above. An element already under the pointer when it mounts gets a mouseenter the first time its hover state is checked, with no pointer movement involved — unlike the DOM, where mouseenter only ever follows an actual move. Its movementX/movementY share the same tracker every other mouse event does, so hovering with no pointer movement since an earlier click can still report a nonzero delta, against that click's position.
Wheel
wheel
The same fields as mousedown, above, plus WheelEvent's:
deltaX/deltaY— scroll distance; positive when scrolling down or right, as in the DOMdeltaZ— always0deltaMode—0(pixels) or1(lines), never2(page)
In a scrolling container, stopPropagation() keeps ancestors' wheel listeners from firing, and the container still scrolls. preventDefault() cancels the scroll. Nested containers scroll the innermost first, and the wheel moves to the next container out once the inner one is at its limit.
The scroll event is not supported.
Keyboard
keydown / keyup
Fire on whichever node is focused, bubbling to its ancestors — with nothing focused, neither reaches any node. A subset of the DOM's KeyboardEvent's fields:
key— DOM-named where recognized, the raw character otherwiserepeat— alwaysfalseforkeyupctrlKey/shiftKey/altKey/metaKey— modifier keys held
There's no code, location, or isComposing yet.
Focus
A node isn't focusable until .focus() has been called on it at least once — clicking a node that's never been focused this way doesn't move focus there, unlike a DOM element with a tabindex.
Once a node has been focused this way, it stays focusable from then on: clicking it moves focus there on its own, the same as a focusable DOM element does. .blur() unfocuses the node only if it is the focused one.
A template ref's own element carries .focus()/.blur() directly, the same as a real DOM element:
<script setup>
import { onMounted, ref } from "@vue/runtime-core";
const input = ref(null);
onMounted(() => input.value.focus());
</script>
<template>
<div ref="input" @focus="onFocused" @blur="onBlurred">...</div>
</template>focus/blur carry no fields of their own.
Propagation
An event bubbles from the node it fired on up through its ancestors, the same as the DOM's. Every listener receives the same three methods to change that:
<script setup>
function onClick(event) {
event.stopPropagation();
}
</script>stopPropagation()/stopImmediatePropagation()— work exactly as the DOM's.preventDefault()— suppresses a native default action: focus's own click-to-focus, a focused node'sclickfiring fromEnter/Space, or awheel's scrolling.
Every listener runs in the bubble phase; there's no way yet to listen during the capture phase.
Event modifiers
Vue's template event modifiers — v-on:click.once, .passive, .capture — are Vue's own syntax, not a web standard.
.onceis fully real: the listener unbinds after its first call..passiveand.captureare accepted but currently degrade to an ordinary bubble-phase listener, for the same reason given in Propagation above — Incarnative.js has no capture-phase dispatch yet, so.capturedoesn't run during the capture phase, and.passivehas no effect beyond a plain bind.
Errors in handlers
An error an @event handler throws goes to the app's app.config.errorHandler and to any onErrorCaptured hooks, as in the browser. With no errorHandler, the host reports it as an application error. A promise that rejects with no handler, such as an async handler that throws, is reported the same way.