Manipulação de Eventos

Escutando Eventos

Você pode usar a diretiva v-on para escutar eventos do DOM e rodar algum JavaScript quando tal evento for disparado.

Por exemplo:

<div id="example-1">
  <button v-on:click="counter += 1">Adiciona 1</button>
  <p>Quantas vezes o botão acima foi clicado: {{ counter }}</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

Resultado:

Quantas vezes o botão acima foi clicado: {{ counter }}

Métodos em Manipuladores

A lógica para muitos manipuladores de evento será mais complexa, sendo assim manter diretamente código JavaScript no valor do atributo v-on não é viável. É por isso que v-on também pode aceitar o nome de um método que você gostaria de chamar.

Por exemplo:

<div id="example-2">
  <!-- `greet` é o nome de um método definido abaixo -->
  <button v-on:click="greet">Cumprimentar</button>
</div>
var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // define métodos dentro do objeto `methods`
  methods: {
    greet: function (event) {
      // `this` dentro de métodos aponta para a instância Vue
      alert('Olá ' + this.name + '!')
      // `event` é o evento DOM nativo
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
})

// você pode invocar métodos no JavaScript também
example2.greet() // => 'Olá Vue.js!'

Resultado:

Chamada Direta de Métodos

Em vez de fazer uma ligação apenas ao nome de um método, também podemos chamar métodos com uma instrução JavaScript diretamente no v-on:

<div id="example-3">
  <button v-on:click="say('oi')">Diga oi</button>
  <button v-on:click="say('tchau')">Diga tchau</button>
</div>
new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})

Resultado:

Às vezes, também precisamos acessar o evento original do DOM em um manipulador. Você pode passá-lo a um método usando a variável especial $event:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Enviar
</button>
// ...
methods: {
  warn: function (message, event) {
    // agora temos acesso ao evento nativo
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

Modificadores de Evento

É muito comum precisar chamar event.preventDefault() ou event.stopPropagation() em manipuladores de eventos. Embora possamos fazer isto facilmente dentro de métodos, seria melhor se os métodos pudessem lidar apenas com a lógica dos dados, em vez de ter que lidar com detalhes de eventos DOM.

Para resolver esse problema, o Vue fornece modificadores de evento para v-on. É só se lembrar que modificadores são sufixos da diretiva, indicados após um ponto.

<!-- a propagação do evento click será interrompida -->
<a v-on:click.stop="doThis"></a>

<!-- o evento submit deixará de recarregar a página -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- modificadores podem ser encadeados -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- é possível utilizar apenas o modificador -->
<form v-on:submit.prevent></form>

<!-- usar modo de captura ao adicionar o evento -->
<!-- ou seja, um evento em um elemento interno é tratado aqui após ser tratado por aquele elemento -->
<div v-on:click.capture="doThis">...</div>

<!-- só aciona o manipulador se event.target é o próprio elemento -->
<!-- isto é, não aciona a partir de um elemento filho -->
<div v-on:click.self="doThat">...</div>

A ordem importa ao utilizar modificadores pois o código relevante é gerado na mesma ordem. Desta forma, v-on:click.prevent.self prevenirá todos os cliques, enquanto v-on:click.self.prevent prevenirá apenas cliques no próprio elemento.

Novo em 2.1.4+

<!-- o evento click será disparado apenas uma vez -->
<a v-on:click.once="doThis"></a>

Diferente dos outros modificadores, exclusivos para eventos nativos, o .once também pode ser usado em eventos de componentes. Se você ainda não leu sobre componentes, não se preocupe com isso neste momento.

Novo em 2.3.0+

Vue também oferece o modificador .passive, correspondendo à opção passive do addEventListener.

<!-- o comportamento padrão do evento scroll (rolar) acontecerá -->
<!-- imediatamente, ao invés de aguardar `onScroll` completar   -->
<!-- para descobrir se ele chama `event.preventDefault()`       -->
<div v-on:scroll.passive="onScroll">...</div>

O .passive é especialmente útil para otimizar desempenho em dispositivos móveis.

Não use .passive e .prevent juntos, pois .prevent será ignorado e seu navegador provavelmente exibirá um aviso. Lembre-se, .passive comunica ao navegador que você não quer prevenir o comportamento padrão do evento.

Modificadores de Teclado

Quando escutamos eventos do teclado, precisamos muitas vezes verificar a ocorrência de teclas específicas. O Vue também permite a adição de modificadores v-on ao escutar eventos de teclado:

<!-- só chama `vm.submit()` quando o `key` é `Enter` -->
<input v-on:keyup.enter="submit">

Você pode usar diretamente qualquer nome de chave válido exposto via KeyboardEvent.key como modificadores, convertendo-os em kebab-case.

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

No exemplo acima, o manipulador só será chamado se $event.key for igual a 'PageDown'.

Key Codes

O uso de eventos keyCode está obsoleto e pode não ser suportado em novos navegadores.

Usando os atributos keyCode também é permitido:

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

O Vue fornece apelidos para os códigos de teclas mais comuns ​​quando necessário para suporte a um navegador legado:

Algumas teclas (.esc e todas as teclas de seta) têm valores key inconsistentes no IE9, portanto, esses apelidos internos devem ter preferência se você precisar dar suporte ao IE9.

Se necessário, defina apelidos personalizados através do objeto global config.keyCodes:

// habilita `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

Teclas Modificadoras de Sistema

Novo em 2.1.0+

Você pode utilizar os modificadores a seguir para acionar eventos de mouse ou teclado apenas quando o modificador correspondente estiver acionado:

Nota: Nos teclados Macintosh, meta é a tecla de comando (⌘). Nos teclados Windows, meta é a tecla Windows (⊞). Nos teclados Sun Microsystems, meta é marcada como um diamante sólido (◆). Em alguns teclados, especificamente em máquinas MIT e Lisp, como o teclado Knight e teclados space-cadet, meta é marcada como “META”. Em teclados Symbolics, meta é marcada como “META” ou “Meta”.

Por exemplo:

<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Faça alguma coisa</div>

Teclas modificadoras são diferentes de teclas comuns, e quando utilizadas com eventos keyup, precisam estar pressionadas quando o evento é emitido. Em outras palavras, keyup.ctrl só vai disparar se você soltar alguma tecla enquanto ainda estiver segurando ctrl. E não irá disparar se você soltar a tecla ctrl sozinha. Se você deseja tal comportamento, use o keyCode para ctrl: keyup.17.

Modificar .exact

Novo em 2.5.0+

O modificador .exact permite controlar a exata combinação de modificadores de sistema que deve ser pressionada para que o gatilho dispare.

<!-- dispara mesmo se Alt ou Shift também estiverem pressionados -->
<button v-on:click.ctrl="onClick">A</button>

<!-- dispara quando somente Ctrl estiver pressionado -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- dispara somente se não houverem teclas de sistema pressionadas -->
<button v-on:click.exact="onClick">A</button>

Modificadores de Mouse

Novo em 2.2.0+

Estes modificadores restringem o manipulador a eventos disparados por um botão específico do mouse, respectivamente o botão da esquerda, o da direita e o central (quando existente).

Por Que Escutas no HTML?

Você pode estar pensando que esta abordagem de escutas de evento viola as boas e velhas práticas sobre “separação de responsabilidades”. Fique tranquilo - como todas as funções de manipuladores e expressões Vue são estritamente ligadas ao ViewModel que está manipulando o modo de exibição atual, essa abordagem não causará qualquer dificuldade de manutenção. Na verdade, há vários benefícios em usar v-on no template:

  1. É mais fácil localizar as implementações de função de manipulador dentro de seu código JS deslizando sobre o template HTML.

  2. Como você não tem que manualmente anexar escutas a eventos em JS, seu código de ViewModel pode conter apenas a lógica pura e está livre de manipulação DOM. Isto torna mais fácil de testar.

  3. Quando um ViewModel é destruído, todas escutas a eventos são removidas automaticamente. Você não precisa se preocupar em removê-las explicitamente.