Обработка событий
Прослушивание событий
Можно использовать директиву v-on
, которую обычно сокращают до символа @
, чтобы прослушивать события DOM и запускать JavaScript-код по их наступлению. Используется как v-on:click="methodName"
или в сокращённом виде @click="methodName"
.
Значение обработчика может быть одним из следующих:
Обработчик события в виде инлайн-кода: Код JavaScript будет выполняться при срабатывании события (аналогично как в нативном атрибуте
onclick
).Обработчик события в виде метода: Имя свойства или путь, указывающий на метод, объявленный в компоненте.
Обработчик события в виде инлайн-кода
Обычно подобный подход используют лишь в очень простых случаях, например:
js
const count = ref(0)
template
<button @click="count++">Добавить 1</button>
<p>Счётчик: {{ count }}</p>
Обработчик события в виде метода
Но чаще всего у многих обработчиков событий логика будет довольно сложной, поэтому оставлять JavaScript-код в значении атрибута v-on
бессмысленно. Поэтому v-on
также принимает имя метода, который потребуется вызвать.
Например:
js
const name = ref('Vue.js')
function greet(event) {
alert(`Привет, ${name.value}!`)
// `event` — нативное событие DOM
if (event) {
alert(event.target.tagName)
}
}
template
<!-- `greet` — название метода, объявленного в компоненте выше -->
<button @click="greet">Поприветствовать</button>
Метод обработчика автоматически получает аргументом нативное событие DOM, которое его вызвало — например, в примере выше можно получить доступ к элементу, на котором произошло событие, через event.target
.
См. также: Аннотация событий
Написание обработчика методом vs. инлайн
Компилятор шаблонов определяет методы обработчиков, проверяя является ли строка значения v-on
допустимым идентификатором JavaScript или путём для обращения к свойству. Например, foo
, foo.bar
и foo['bar']
будут рассматриваться как обработчики методов, а foo()
и count++
— как инлайн.
Вызов методов в инлайн-обработчиках
Вместо привязки непосредственно к имени метода, можно вызывать методы и в инлайн-обработчике. Это позволит передавать в метод вместо нативного события другие аргументы:
js
function say(message) {
alert(message)
}
template
<button @click="say('привет')">Скажи привет</button>
<button @click="say('пока')">Скажи пока</button>
Доступ к событию через аргумент в инлайн-обработчиках
Иногда может потребоваться получить доступ к оригинальному событию DOM в инлайн-обработчике. Его можно явно передать в метод с помощью специальной переменной $event
или воспользоваться стрелочной функцией:
template
<!-- использование специальной переменной $event -->
<button @click="warn('Форму пока ещё нельзя отправить.', $event)">
Отправить
</button>
<!-- использование стрелочной функции в инлайн-выражении -->
<button @click="(event) => warn('Форму пока ещё нельзя отправить.', event)">
Отправить
</button>
js
function warn(message, event) {
// теперь есть доступ к нативному событию
if (event) {
event.preventDefault()
}
alert(message)
}
Модификаторы событий
Часто необходимо вызвать event.preventDefault()
или event.stopPropagation()
внутри обработчиков события. Хотя это и легко можно делать внутри методов, но лучше когда методы содержат в себе только логику и не имеют дела с деталями реализации событий DOM.
Vue для решения этой задачи предоставляет модификаторы событий для v-on
. Вспомните, что модификаторы — это постфиксы директивы, отделяемые точкой:
.stop
.prevent
.self
.capture
.once
.passive
template
<!-- всплытие события click будет остановлено -->
<a @click.stop="doThis"></a>
<!-- событие submit перестанет перезагружать страницу -->
<form @submit.prevent="onSubmit"></form>
<!-- модификаторы можно объединять в цепочки -->
<a @click.stop.prevent="doThat"></a>
<!-- можно использовать без указания обработчиков -->
<form @submit.prevent></form>
<!-- вызов обработчика только в случае наступления события непосредственно -->
<!-- на данном элементе (то есть не на дочернем компоненте) -->
<div @click.self="doThat">...</div>
Совет
При использовании модификаторов имеет значение их порядок, потому что в той же очерёдности генерируется и соответствующий код. Поэтому @click.prevent.self
предотвратит действие клика по умолчанию на самом элементе и на его дочерних элементах, в то время как @click.self.prevent
предотвратит действие клика по умолчанию только на самом элементе.
Модификаторы .capture
, .once
и .passive
зеркально отражают действия опций нативного метода addEventListener
:
template
<!-- можно отслеживать события в режиме capture, -->
<!-- т.е. событие, нацеленное на внутренний элемент, -->
<!-- обработается здесь до обработки этим элементом -->
<div @click.capture="doThis">...</div>
<!-- обработчик click будет вызван максимум 1 раз -->
<a @click.once="doThis"></a>
<!-- по умолчанию событие scroll (при прокрутке) произойдёт -->
<!-- незамедлительно, вместо ожидания окончания `onScroll` -->
<!-- на случай, если там будет `event.preventDefault()` -->
<div @scroll.passive="onScroll">...</div>
Модификатор .passive
особенно полезен для улучшения производительности на мобильных устройствах.
Совет
Не указывайте вместе .passive
и .prevent
— .prevent
будет проигнорирован и браузер скорее всего покажет предупреждение. Запомните, что .passive
сообщает браузеру, что для события не будет предотвращаться поведение по умолчанию.
Модификаторы клавиш
При прослушивании событий клавиатуры часто требуется отслеживать конкретные клавиши. Vue позволяет указывать модификаторы клавиш при использовании v-on
или @
при прослушивании событий клавиш:
template
<!-- вызвать `vm.submit()` только если `key` клавиши будет `Enter` -->
<input @keyup.enter="submit" />
Можно использовать любые допустимые имена клавиш напрямую, используя в качестве модификаторов ключи KeyboardEvent.key
и указывая их имена в формате kebab-case.
template
<input @keyup.page-down="onPageDown" />
В этом примере обработчик вызовется только когда $event.key
будет 'PageDown'
.
Псевдонимы клавиш
Vue предоставляет псевдонимы для наиболее часто используемых клавиш:
.enter
.tab
.delete
(ловит как «Delete», так и «Backspace»).esc
.space
.up
.down
.left
.right
Модификаторы системных клавиш
Можно использовать следующие модификаторы для прослушивания событий мыши или клавиатуры только при зажатой клавиши-модификатора:
.ctrl
.alt
.shift
.meta
Примечание
На клавиатурах Apple клавиша meta отмечена знаком ⌘. На клавиатурах Windows клавиша meta отмечена знаком ⊞. На клавиатурах Sun Microsystems клавиша meta отмечена символом ромба ◆. На некоторых клавиатурах, особенно MIT и Lisp machine и их преемников, таких как Knight или space-cadet клавиатуры, клавиша meta отмечена словом «META». На клавиатурах Symbolics, клавиша meta отмечена словом «META» или «Meta».
Например:
template
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Сделать что-нибудь</div>
Совет
Обратите внимание, клавиши-модификаторы отличаются от обычных клавиш и при отслеживании событий keyup
должны быть нажаты, когда событие происходит. Другими словами, keyup.ctrl
будет срабатывать только если отпустить клавишу, удерживая нажатой ctrl
. Это не сработает, если отпустить только клавишу ctrl
.
Модификатор .exact
Модификатор .exact
позволяет контролировать точную комбинацию модификаторов системных клавиш, необходимых для запуска события.
template
<!-- сработает, даже если также будут нажаты Alt или Shift -->
<button @click.ctrl="onClick">A</button>
<!-- сработает, только когда нажат Ctrl и не нажаты никакие другие клавиши -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- сработает, только когда не нажаты никакие системные модификаторы -->
<button @click.exact="onClick">A</button>
Модификаторы кнопок мыши
.left
.right
.middle
Эти модификаторы ограничивают обработчик события только вызовами по определённой кнопке мыши.