# 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.