title | type | order |
---|---|---|
Manipulação de Eventos |
guide |
9 |
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:
{% raw %}
Quantas vezes o botão acima foi clicado: {{ counter }}
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:
{% raw %}
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: {% raw %}
À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)
}
}
É 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.
.stop
.prevent
.capture
.self
.once
.passive
<!-- 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.
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'
.
O uso de eventos `keyCode` [está obsoleto](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) 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:
.enter
.tab
.delete
(captura tanto "Delete" quanto "Backspace").esc
.space
.up
.down
.left
.right
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
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:
.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, 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`.
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>
Novo em 2.2.0+
.left
.right
.middle
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).
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:
-
É mais fácil localizar as implementações de função de manipulador dentro de seu código JS deslizando sobre o template HTML.
-
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.
-
Quando um ViewModel é destruído, todas escutas a eventos são removidas automaticamente. Você não precisa se preocupar em removê-las explicitamente.