Обработка событий

Подписка на события

Чтобы подписаться на события DOM и выполнить JavaScript-код по их наступлении, примените директиву v-on.

Например:

<div id="example-1">
<button v-on:click="counter += 1">+1</button>
<p>Кнопка выше была нажата {{counter}} раз</p>
</div>
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})

Результат:

Кнопка выше была нажата {{counter}} раз

Обработчики событий

Логика обработки события может быть довольно сложной, так что оставить весь JavaScript-код в значении атрибута v-on не всегда возможно. В этом случае v-on может принять и название метода, который вы хотите вызвать.

Например:

<div id="example-2">
<!-- `greet` — это название метода, определённого ниже -->
<button v-on:click="greet">Поприветствовать</button>
</div>
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// определяйте методы в объекте `methods`
methods: {
greet: function (event) {
// `this` внутри методов указывает на экземпляр Vue
alert('Привет, ' + this.name + '!')
// `event` — нативное событие DOM
if (event) {
alert(event.target.tagName)
}
}
}
})
// вызывать методы можно и императивно
example2.greet() // => 'Привет, Vue.js!'

Результат:

Методы и inline-обработчики

Можно связаться с методом не по имени, а вызвав его в JavaScript-выражении:

<div id="example-3">
<button v-on:click="say('hi')">Скажи hi</button>
<button v-on:click="say('what')">Скажи what</button>
</div>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})

Результат:

Иногда и в inline-обработчиках оказывается необходим доступ к оригинальному событию DOM. Его можно передать в метод, используя специальную переменную $event:

<button v-on:click="warn('Форма пока не может быть отправлена.', $event)">
Отправить
</button>
// ...
methods: {
warn: function (message, event) {
// теперь у нас есть доступ к нативному событию
if (event) event.preventDefault()
alert(message)
}
}

Модификаторы событий

Очень часто возникает необходимость вызвать event.preventDefault() или event.stopPropagation() в обработчике события. Хотя это легко можно сделать внутри метода, было бы лучше сохранить чистоту логики и абстрагироваться от деталей реализации событий DOM.

Для решения этой задачи Vue предлагает модификаторы событий для v-on. Напомним, что модификаторы директив указываются как постфиксы и отделяются точкой.

<!-- событие click не будет всплывать дальше -->
<a v-on:click.stop="doThis"></a>
<!-- событие submit больше не будет перезагружать страницу -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- модификаторы можно объединять в цепочки -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- и использовать без указания пользовательского обработчика -->
<form v-on:submit.prevent></form>
<!-- при добавлении слушателя события можно использовать capture mode -->
<!-- т.е. событие направленное на внутренний элемент сначала обрабатывается здесь перед тем, как обрабатываться этим элементом -->
<div v-on:click.capture="doThis">...</div>
<!-- вызывать обработчик только в случае наступления события непосредственно -->
<!-- на данном элементе (то есть не на дочернем компоненте) -->
<div v-on:click.self="doThat">...</div>

Порядок имеет значение при использовании модификаторов, потому что код генерируется в том же порядке. Поэтому использование @click.prevent.self будет предотвращать все клики, в то время как @click.self.prevent будет предотвращать клики только на самом элементе.

Добавлено в версии 2.1.4+

<!-- Событие click сработает только 1 раз -->
<a v-on:click.once="doThis"></a>

В отличие от остальных модификаторов, которые поддерживают исключительно нативные DOM-события, модификатор .once можно использовать и в пользовательских событиях компонентов. Если вы ещё не читали о компонентах, не беспокойтесь об этом сейчас.

Модификаторы клавиш

При обработке событий от клавиатуры нас часто интересуют распространённые коды клавиш. Vue позволяет добавить модификаторы клавиш при использовании v-on для отслеживания событий от клавиатуры:

<!-- вызвать vm.submit() только если keyCode равно 13 -->
<input v-on:keyup.13="submit">

Удерживать все коды клавиш в памяти — неблагодарное дело, поэтому Vue предоставляет псевдонимы для наиболее часто используемых из них:

<!-- аналогично примеру выше -->
<input v-on:keyup.enter="submit">
<!-- работает также и в сокращённой записи -->
<input @keyup.enter="submit">

Вот полный список поддерживаемых псевдонимов:

Вы можете также определить пользовательские псевдонимы клавиш через глобальный объект config.keyCodes:

// включит v-on:keyup.f1
Vue.config.keyCodes.f1 = 112

Модификаторы клавиш

Добавлено в версии 2.1.0+

Вы можете использовать следующие модификаторы для отслеживания событий мыши или клавиатуры с зажатой клавишей-модификатором:

Примечание: На клавиатурах Apple клавиша meta отмечена знаком ⌘. На клавиатурах Windows клавиша meta отмечена знаком ⊞. На клавиатурах Sun Microsystems клавиша meta отмечена символом ромба (◆). На некоторых клавиатурах, особенно MIT и Lisp machine и их преемников, таких как Knight-клавиатуры или space-cadet клавиатуры, клавиша meta отмечена словом “META”. На клавиатурах Symbolics, meta-клавиша отмечена словом “META” или “Meta”.

Например:

<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Сделать что-нибудь</div>

Обратите внимание, клавиши-модификаторы отличаются от обычных клавиш и при использовании событий keyup они должны быть нажаты, когда событие генерируется. Другими словами, keyup.ctrl сработает только тогда, когда вы отпустите клавишу, удерживая нажатой ctrl. Это не сработает, если вы отпустите только клавишу ctrl.

Модификаторы клавиш мыши

Добавлено в версии 2.2.0+

Эти модификаторы ограничивают обработчик события только вызовами определённой кнопкой мыши.

Почему подписчики указываются в HTML?

Может показаться, что такой подход к отслеживанию событий нарушает старое доброе правило “разделения мух и котлет”. Не беспокойтесь — поскольку все обработчики во Vue строго связываются с ответственным за текущее представление экземпляром vm, трудностей в поддержке не возникает. На практике, есть даже несколько преимуществ при использовании v-on:

  1. Легче получить представление об имеющихся обработчиках, просто пробежав глазами по HTML-коду шаблона.

  2. Поскольку нет необходимости вручную привязывать слушатели событий в JS, код vm остаётся независимым от DOM и содержит только необходимую логику. Это облегчает тестирование.

  3. Когда vm уничтожается, все слушатели событий автоматически удаляются. Нет необходимости волноваться о том, что придётся прибираться за собой.