Перейти к содержанию

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

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

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

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

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

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

Встроенные обработчики

Встроенные обработчики обычно используются в простых случаях, например:

js
const count = ref(0)
js
data() {
  return {
    count: 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)
  }
}
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, который его запускает — в примере выше мы можем получить доступ к элементу, отправившему событие, через event.target.

Метод против встроенного обнаружения

Компилятор шаблонов обнаруживает обработчики методов, проверяя, является ли строка значения 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('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)
}
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
<!-- распространение события щелчка будет остановлено -->
<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.

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