Skip to content

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

Прослушивание событий

Можно использовать директиву v-on, которую обычно сокращают до символа @, чтобы прослушивать события DOM и запускать JavaScript-код по их наступлению. Используется как v-on:click="methodName" или в сокращённом виде @click="methodName".

Значение обработчика может быть одним из следующих:

  1. Обработчик события в виде инлайн-кода: Код JavaScript будет выполняться при срабатывании события (аналогично как в нативном атрибуте onclick).

  2. Обработчик события в виде метода: Имя свойства или путь, указывающий на метод, объявленный в компоненте.

Обработчик события в виде инлайн-кода

Обычно подобный подход используют лишь в очень простых случаях, например:

js
const count = ref(0)
js
data() {
  return {
    count: 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)
  }
}
js
data() {
  return {
    name: 'Vue.js'
  }
},
methods: {
  greet(event) {
    // `this` в методе указывает на текущий активный экземпляр
    alert(`Привет, ${this.name}!`)
    // `event` — нативное событие DOM
    if (event) {
      alert(event.target.tagName)
    }
  }
}
template
<!-- `greet` — название метода, объявленного в компоненте выше -->
<button @click="greet">Поприветствовать</button>

Метод обработчика автоматически получает аргументом нативное событие DOM, которое его вызвало — например, в примере выше можно получить доступ к элементу, на котором произошло событие, через event.target.tagName.

Написание обработчика методом vs. инлайн

Компилятор шаблонов определяет методы обработчиков, проверяя является ли строка значения v-on допустимым идентификатором JavaScript или путём для обращения к свойству. Например, foo, foo.bar и foo['bar'] будут рассматриваться как обработчики методов, а foo() и count++ — как инлайн.

Вызов методов в инлайн-обработчиках

Вместо привязки непосредственно к имени метода, можно вызывать методы и в инлайн-обработчике. Это позволит передавать в метод вместо нативного события другие аргументы:

js
function say(message) {
  alert(message)
}
js
methods: {
  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)
}
js
methods: {
  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

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

Обработка событийУже загружено