vue2_rus

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

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

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

// вызывать методы можно и императивно
example2.greet() // => 'Привет, Vue.js!'

Результат:

Методы и встрочные-обработчики

Кроме указания имени метода, можно использовать и JavaScript-выражения:

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

Результат:

Иногда в встрочных-обработчиках необходим доступ к оригинальному событию 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, т.е. событие, нацеленное -->
<!-- на внутренний элемент, обрабатывается здесь до обработки этим элементом -->
<div v-on:click.capture="doThis">...</div>

<!-- вызов обработчика только в случае наступления события непосредственно -->
<!-- на данном элементе (то есть не на дочернем компоненте) -->
<div v-on:click.self="doThat">...</div>

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

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

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

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

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

Vue также предоставляет изменитель .passive, соответствующий настройке passive в addEventListener.

<!-- по умолчанию событие scroll (при прокрутке) произойдёт -->
<!-- незамедлительно, вместо ожидания окончания `onScroll`  -->
<!-- на случай, если там будет `event.preventDefault()`     -->
<div v-on:scroll.passive="onScroll">...</div>

Изменитель .passive особенно полезен для повышения производительности на мобильных устройствах.

Не используйте вместе .passive и .prevent, потому что .prevent будет проигнорирован и обозреватель возможно покажет предупреждение. Помните, что .passive сообщает обозревателю, что вы не хотите предотвращать поведение по умолчанию для события.

Изменители клавиш

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

<!-- вызвать `vm.submit()` только если `key` будет `Enter` -->
<input v-on:keyup.enter="submit">

Можно также использовать любые допустимые имена клавиш, предоставляемые через KeyboardEvent.key в качестве изменителей, именуя их в kebab-case.

<input v-on:keyup.page-down="onPageDown">

В примере выше обработчик будет вызываться только если $event.key будет 'PageDown'.

Коды клавиш

Использование значения keyCode событий — устаревшая практика и может не поддерживаться в новых обозревателях.

Использование значений keyCode также разрешено:

<input v-on:keyup.13="submit">

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

Некоторые клавиши (.esc и все клавиши со стрелками) имеют несогласованные значения в IE9, поэтому их встроенные псевдонимы должны быть предпочтительными, если необходимо поддерживать IE9.

Можно также определить пользовательские псевдонимы клавиш через глобальную настройку 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 v-on:keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Сделать что-нибудь</div>

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

Изменитель .exact

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

Изменитель .exact позволяет контролировать точную комбинацию системных изменителей, необходимых для запуска события.

<!-- сработает, даже если Alt или Shift также нажаты -->
<button v-on:click.ctrl="onClick">A</button>

<!-- сработает, только когда нажат Ctrl и не нажаты никакие другие клавиши -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- сработает, только когда не нажаты никакие системные изменители -->
<button v-on:click.exact="onClick">A</button>

Изменители клавиш мыши

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

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

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

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

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

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

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