Обработка событий
Прослушивание событий
Мы можем использовать директиву v-on
, которую обычно сокращают до символа @
, для прослушивания событий DOM и запуска некоторого JavaScript при их наступлении. Использовать можно v-on:click="handler"
или с помощью сокращения @click="handler"
.
Значение обработчика может быть одним из следующих:
Встроенные обработчики: встроенный код JavaScript, который будет выполняться при срабатывании события (аналогично встроенному атрибуту onclick).
Обработчики методов. Имя свойства или путь, указывающий на метод, определённый в компоненте.
Встроенные обработчики
Встроенные обработчики обычно используются в простых случаях, например:
js
const count = ref(0)
template
<button @click="count++">Добавить 1</button>
<p>Счётчик: {{ count }}</p>
Обработчики методов
Однако логика многих обработчиков событий будет более сложной и, скорее всего, не будет реализована с помощью встроенных обработчиков. Поэтому 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, который его запускает — в примере выше мы можем получить доступ к элементу, отправившему событие, через event.target
.
Смотрите также: Типизация обработчиков событий
Метод против встроенного обнаружения
Компилятор шаблонов обнаруживает обработчики методов, проверяя, является ли строка значения v-on
корректным идентификатором JavaScript или путём доступа к свойству. Например, foo
, foo.bar
и foo['bar']
рассматриваются как обработчики методов, а foo()
и count++
— как встроенные обработчики.
Вызов методов во встроенных обработчиках
Вместо того чтобы привязываться непосредственно к имени метода, мы можем вызывать методы во встроенном обработчике. Это позволяет нам передавать методу пользовательские аргументы вместо собственных событий:
js
function say(message) {
alert(message)
}
template
<button @click="say('hello')">Поздороваться</button>
<button @click="say('bye')">Попрощаться</button>
Доступ к аргументу события во встроенных обработчиках
Иногда нам также нужно получить доступ к исходному событию DOM во встроенном обработчике. Вы можете передать его в метод с помощью специальной переменной $event
или использовать встроенную функцию-стрелку:
template
<!-- использование специальной переменной $event -->
<button @click="warn('Форма пока не может быть отправлена.', $event)">
Submit
</button>
<!-- использование встроенной стрелочной функции -->
<button @click="(event) => warn('Форма пока не может быть отправлена.', event)">
Submit
</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
<!-- распространение события щелчка будет остановлено -->
<a @click.stop="doThis"></a>
<!-- событие отправки больше не будет перезагружать страницу -->
<form @submit.prevent="onSubmit"></form>
<!-- модификаторы могут быть соединены в цепочку -->
<a @click.stop.prevent="doThat"></a>
<!-- только модификатор -->
<form @submit.prevent></form>
<!-- обработчик срабатывает только в том случае, если event.target является самим элементом -->
<!-- т.е. не из дочернего элемента -->
<div @click.self="doThat">...</div>
Примечание
Порядок имеет значение при использовании модификаторов, поскольку соответствующий код генерируется в том же порядке. Поэтому использование @click.prevent.self
предотвратит действие клика по умолчанию на сам элемент и его дочерние элементы, в то время как @click.self.prevent
предотвратит действие клика по умолчанию только на сам элемент.
Модификаторы .capture
, .once
и .passive
повторяют параметры нативного метода addEventListener
:
template
<!-- используйте режим захвата при добавлении слушателя событий -->
<!-- т. е. событие, направленное на внутренний элемент, обрабатывается здесь, -->
<!-- прежде чем будет обработано этим элементом -->
<div @click.capture="doThis">...</div>
<!-- событие щелчка будет вызвано не более одного раза -->
<a @click.once="doThis"></a>
<!-- будет происходить стандартное поведение события прокрутки -->
<!-- немедленно, вместо того чтобы ждать завершения `onScroll`. -->
<!-- в случае, если он содержит `event.preventDefault()`. -->
<div @scroll.passive="onScroll">...</div>
Модификатор .passive
обычно используется в слушателях сенсорных событий для улучшения производительности на мобильных устройствах.
Совет
Не используйте .passive
и .prevent
вместе, потому что .passive
уже указывает браузеру, что вы не намерены предотвращать поведение события по умолчанию, и вы, скорее всего, увидите предупреждение от браузера, если сделаете это.
Модификаторы клавиш
При прослушивании событий клавиатуры нам часто нужно проверить наличие определённых клавиш. Vue позволяет добавлять модификаторы клавиш v-on
или @
при прослушивании событий клавиатуры:
template
<!-- вызывайте `submit` только тогда, когда `key` - `Enter` -->
<input @keyup.enter="submit" />
Вы можете напрямую использовать любые имена допустимых клавиш, отображаемые через KeyboardEvent.key
, в качестве модификаторов, преобразовав их в кебабный регистр.
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
Примечание
На клавиатурах Macintosh meta
— это клавиша command (⌘). На клавиатурах Windows meta
— это клавиша Windows (⊞). На клавиатурах Sun Microsystems meta
обозначается сплошным ромбом (◆). На некоторых клавиатурах, в частности, на клавиатурах машин MIT и Lisp и их преемниках, таких как клавиатура Knight, клавиатура с пробелами, meta
обозначается как «META». На клавиатурах Symbolics мета обозначается как «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
Эти модификаторы ограничивают обработчик событиями, вызванными определённой кнопкой мыши.
Обратите внимание, однако, что имена модификаторов .left
, .right
и .middle
основаны на типичной раскладке мыши для правшей, но на самом деле представляют собой триггеры событий указательных устройств main
(основной), secondary
(вторичный) и auxiliary
(дополнительный) соответственно, а не фактические физические кнопки. Таким образом, для раскладки мыши для левшей «основная» кнопка может физически быть правой, но будет вызывать обработчик модификатора .left
. Или трекпад может вызывать обработчик .left
при однократном касании одним пальцем, обработчик .right
при касании двумя пальцами и обработчик .middle
при касании тремя пальцами. Аналогично, другие устройства и источники событий, генерирующие события mouse
, могут иметь режимы триггера, которые вообще не связаны с .left
и .right
.