# Manipulação de Eventos

Aprenda como manipular eventos em uma aula gratuita da Vue School

# Escutando Eventos

Podemos usar a diretiva v-on, que normalmente abreviamos para o símbolo @, para escutar eventos do DOM e rodar algum JavaScript quando tal evento for disparado. A maneira de usar seria v-on:click="nomeDoMétodo" ou com o atalho, @click="nomeDoMétodo"

Por exemplo:

<div id="basic-event">
  <button @click="counter += 1">Adicionar 1</button>
  <p>O botão acima foi clicado {{counter}} vezes.</p>
</div>
1
2
3
4
Vue.createApp({
  data() {
    return {
      counter: 0
    }
  }
}).mount('#basic-event')
1
2
3
4
5
6
7

Resultado:

Veja o exemplo Exemplo básico de manipulação de eventos por vuejs-br (@vuejs-br) no CodePen.

# Métodos em Manipuladores

A lógica para muitos manipuladores de evento será mais complexa, portanto, 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="event-with-method">
  <!-- `greet` é o nome de um método definido abaixo -->
  <button @click="greet">Cumprimentar</button>
</div>
1
2
3
4
Vue.createApp({
  data() {
    return {
      name: 'Vue.js'
    }
  },
  methods: {
    greet(event) {
      // `this` dentro de métodos aponta para a atual instância Vue ativa
      alert('Olá ' + this.name + '!')
      // `event` é o evento DOM nativo
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
}).mount('#event-with-method')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Resultado:

Veja o exemplo Exemplo de manipulação de eventos com um método por vuejs-br (@vuejs-br) no CodePen.

# Chamada Direta de Métodos

Em vez de interligar o evento diretamente ao nome de um método, também podemos chamar métodos diretamente com uma instrução JavaScript:

<div id="inline-handler">
  <button @click="say('oi')">Diga oi</button>
  <button @click="say('tchau')">Diga tchau</button>
</div>
1
2
3
4
Vue.createApp({
  methods: {
    say(message) {
      alert(message)
    }
  }
}).mount('#inline-handler')
1
2
3
4
5
6
7

Resultado:

Veja o exemplo Exemplo de evento com chamada direta de métodoo por vuejs-br (@vuejs-br) no CodePen.

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

<button @click="warn('O formulário ainda não pode ser enviado.', $event)">
  Enviar
</button>
1
2
3
// ...
methods: {
  warn(message, event) {
    // agora temos acesso ao evento nativo
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}
1
2
3
4
5
6
7
8
9
10

# Múltiplos Manipuladores de Eventos

Você pode ter vários métodos em um manipulador de eventos separados por vírgula, desta forma:

<!-- ambos one() e two() serão executados no clique do botão -->
<button @click="one($event), two($event)">
  Enviar
</button>
1
2
3
4
// ...
methods: {
  one(event) {
    // lógica do primeiro manipulador...
  },
  two(event) {
    // lógica do segundo manipulador...
  }
}
1
2
3
4
5
6
7
8
9

# 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, Vue fornece modificadores de evento para v-on. É só se lembrar que modificadores são sufixos da diretiva, denotados por um ponto.

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- a propagação do evento click será interrompida -->
<a @click.stop="doThis"></a>

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

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

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

<!-- usar modo de captura ao adicionar o evento -->
<!-- ou seja, um evento em um elemento interno é tratado aqui antes de ser tratado por aquele elemento -->
<div @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 @click.self="doThat">...</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Nota

A ordem importa ao utilizar modificadores pois o código relevante é gerado na mesma ordem. Desta forma, @click.prevent.self prevenirá a ação padrão do clique no próprio elemento e seus filhos, enquanto @click.self.prevent prevenirá apenas a ação padrão de cliques no próprio elemento.

<!-- o evento click será disparado apenas uma vez -->
<a @click.once="doThis"></a>
1
2

Diferente dos outros modificadores, que são exclusivos para eventos nativos, o modificador .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.

Vue também oferece o modificador .passive, correspondendo à opção passive do addEventListener (opens new window).

<!-- 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 @scroll.passive="onScroll">...</div>
1
2
3
4

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

Nota

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 ou @ ao escutar eventos de teclado:

<!-- só chama `vm.submit()` quando o `key` é `Enter` -->
<input @keyup.enter="submit" />
1
2

Você pode usar diretamente qualquer nome de tecla válido exposto via KeyboardEvent.key (opens new window) como modificadores, convertendo-os em kebab-case.

<input @keyup.page-down="onPageDown" />
1

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

# Apelidos de Teclas

Vue fornece apelidos para os códigos de teclas mais comuns:

  • .enter
  • .tab
  • .delete (captura tanto "Delete" quanto "Backspace")
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

# Modificadores de Teclas do Sistema

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

  • .ctrl
  • .alt
  • .shift
  • .meta

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 e suas sucessoras, assim como o teclado Knight e teclados space-cadet, meta é marcada como “META”. Em teclados Symbolics, meta é marcada como “META” ou “Meta”.

Por exemplo:

<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Faça alguma coisa</div>
1
2
3
4
5

TIP

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.

# Modificador .exact

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 @click.ctrl="onClick">A</button>

<!-- dispara somente quando Ctrl (e nenhuma outra tecla) for pressionado -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- dispara somente se não houverem teclas do sistema pressionadas -->
<button @click.exact="onClick">A</button>
1
2
3
4
5
6
7
8

# Modificadores dos Botões do Mouse

  • .left
  • .right
  • .middle

Estes modificadores restringem o manipulador à eventos disparados por um botão específico do mouse.

# 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 ou @:

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

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

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