Saltar al contenido

Manejo de Eventos

Escuchando Eventos

Podemos usar la directiva v-on, que usualmente abreviamos con el símbolo @, para escuchar eventos del DOM y ejecutar algo de JavaScript cuando estos se disparan. El uso sería v-on:click="handler" o, con el atajo, @click="handler".

El valor del manejador puede ser uno de los siguientes:

  1. Manejadores en línea: JavaScript en línea que se ejecutará cuando el evento sea disparado (similar al atributo nativo onclick).

  2. Manejadores de método: Un nombre de propiedad o ruta que apunta a un método definido en el componente.

Manejadores en Línea

Los manejadores en línea se usan típicamente en casos sencillos, por ejemplo:

js
const count = ref(0)
js
data() {
  return {
    count: 0
  }
}
template
<button @click="count++">Añadir 1</button>
<p>La Cuenta es: {{ count }}</p>

Manejadores de Método

Sin embargo, la lógica para muchos manejadores de eventos será más compleja y probablemente no sea factible con manejadores en línea. Es por eso que v-on también puede aceptar el nombre o la ruta de un método del componente que te gustaría llamar.

Por ejemplo:

js
const name = ref('Vue.js')

function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` es el evento nativo del DOM
  if (event) {
    alert(event.target.tagName)
  }
}
js
data() {
  return {
    name: 'Vue.js'
  }
},
methods: {
  greet(event) {
    // `this` dentro de los métodos apunta a la instancia activa actual
    alert(`¡Hola ${this.name}!`)
    // `event` es el evento nativo del DOM
    if (event) {
      alert(event.target.tagName)
    }
  }
}
template
<!-- `greet` es el nombre del método definido anteriormente -->
<button @click="greet">Saludar</button>

Un manejador de método recibe automáticamente el objeto nativo DOM Event que lo dispara; en el ejemplo anterior, podemos acceder al elemento que despacha el evento a través de event.target.

Detección de Método vs. En Línea

El compilador de templates detecta los manejadores de método comprobando si la cadena de valor de v-on es un identificador de JavaScript válido o una ruta de acceso a una propiedad. Por ejemplo, foo, foo.bar y foo['bar'] se tratan como manejadores de método, mientras que foo() y count++ se tratan como manejadores en línea.

Llamando Métodos en Manejadores en Línea

En lugar de enlazar directamente a un nombre de método, también podemos llamar métodos en un manejador en línea. Esto nos permite pasar argumentos personalizados al método en lugar del evento nativo:

js
function say(message) {
  alert(message)
}
js
methods: {
  say(message) {
    alert(message)
  }
}
template
<button @click="say('hello')">Di hola</button>
<button @click="say('bye')">Di adiós</button>

Accediendo al Argumento Event en Manejadores en Línea

A veces también necesitamos acceder al evento DOM original en un manejador en línea. Puedes pasarlo a un método usando la variable especial $event, o usar una función de flecha en línea:

template
<!-- usando la variable especial $event -->
<button @click="warn('El formulario no se puede enviar todavía.', $event)">
  Enviar
</button>

<!-- usando la función flecha en línea -->
<button @click="(event) => warn('El formulario no se puede enviar todavía.', event)">
  Enviar
</button>
js
function warn(message, event) {
  // ahora tenemos acceso al evento nativo
  if (event) {
    event.preventDefault()
  }
  alert(message)
}
js
methods: {
  warn(message, event) {
    // ahora tenemos acceso al evento nativo
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

Modificadores de Evento

Es una necesidad muy común llamar a event.preventDefault() o event.stopPropagation() dentro de los manejadores de eventos. Aunque podemos hacer esto fácilmente dentro de los métodos, sería mejor si los métodos pudieran ser puramente sobre lógica de datos en lugar de tener que lidiar con los detalles de los eventos DOM.

Para abordar este problema, Vue proporciona modificadores de evento para v-on. Recuerda que los modificadores son sufijos de directiva denotados por un punto.

  • .stop
  • .prevent
  • .self
  • .capture
  • .once
  • .passive
template
<!-- se detendrá la propagación del evento de clic -->
<a @click.stop="doThis"></a>

<!-- el evento submit ya no recargará la página -->
<form @submit.prevent="onSubmit"></form>

<!-- los modificadores se pueden encadenar -->
<a @click.stop.prevent="doThat"></a>

<!-- solo el modificador -->
<form @submit.prevent></form>

<!-- solo se activará el controlador si event.target es el propio elemento -->
<!-- es decir, no desde un elemento secundario -->
<div @click.self="doThat">...</div>

TIP

El orden importa al usar modificadores porque el código relevante se genera en el mismo orden. Por lo tanto, usar @click.prevent.self evitará la acción predeterminada de click en el elemento mismo y en sus hijos, mientras que @click.self.prevent solo evitará la acción predeterminada de click en el elemento mismo.

Los modificadores .capture, .once y .passive reflejan las opciones del método nativo addEventListener:

template
<!-- usa el modo de captura al agregar el detector de eventos -->
<!-- es decir, se gestiona un evento dirigido a un elemento   -->
<!-- interno aquí antes de que lo gestione ese elemento       -->
<div @click.capture="doThis">...</div>

<!-- el evento clic se activará como máximo una vez -->
<a @click.once="doThis"></a>

<!-- el comportamiento por defecto del evento de scroll (desplazamiento) -->
<!-- se producirá inmediatamente, en lugar de esperar a que se complete  -->
<!-- `onScroll` en caso de que contenga `event.preventDefault()`         -->
<div @scroll.passive="onScroll">...</div>

El modificador .passive se utiliza típicamente con listeners de eventos táctiles para mejorar el rendimiento en dispositivos móviles.

TIP

No uses .passive y .prevent juntos, porque .passive ya indica al navegador que no tienes la intención de prevenir el comportamiento predeterminado del evento, y es probable que veas una advertencia del navegador si lo haces.

Modificadores de Tecla

Al escuchar eventos de teclado, a menudo necesitamos verificar teclas específicas. Vue permite agregar modificadores de tecla para v-on o @ al escuchar eventos de teclado:

template
<!-- solo llama a `submit` cuando la `tecla` sea `Enter` -->
<input @keyup.enter="submit" />

Puedes usar directamente cualquier nombre de tecla válido expuesto a través de KeyboardEvent.key como modificadores, convirtiéndolos a kebab-case.

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

En el ejemplo anterior, el manejador solo se llamará si $event.key es igual a 'PageDown'.

Alias de Teclas

Vue proporciona alias para las teclas más comúnmente usadas:

  • .enter
  • .tab
  • .delete (captura las teclas "Delete" y "Backspace")
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

Teclas Modificadoras del Sistema

Puedes usar los siguientes modificadores para disparar listeners de eventos de ratón o teclado solo cuando se presiona la tecla modificadora correspondiente:

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

Nota

En teclados Macintosh, meta es la tecla de comando (⌘). En teclados Windows, meta es la tecla de Windows (⊞). En teclados Sun Microsystems, meta se marca como un diamante sólido (◆). En ciertos teclados, específicamente MIT y los teclados de máquinas Lisp y sus sucesores, como el teclado Knight, el teclado space-cadet, meta se etiqueta como "META". En teclados Symbolics, meta se etiqueta como "META" o "Meta".

Por ejemplo:

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

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Hacer algo</div>

TIP

Ten en cuenta que las teclas modificadoras son diferentes de las teclas regulares y, cuando se usan con eventos keyup, deben estar presionadas cuando se emite el evento. En otras palabras, keyup.ctrl solo se disparará si sueltas una tecla mientras mantienes presionado ctrl. No se disparará si sueltas la tecla ctrl sola.

Modificador .exact

El modificador .exact permite controlar la combinación exacta de modificadores del sistema necesaria para disparar un evento.

template
<!-- esto se activará incluso si también se presiona Alt o Shift -->
<button @click.ctrl="onClick">A</button>

<!-- esto solo se activará cuando se presione Ctrl y ninguna otra tecla -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- esto solo se activará cuando no se presione modificadores del sistema -->
<button @click.exact="onClick">A</button>

Modificadores de Botón del Ratón

  • .left
  • .right
  • .middle

Estos modificadores restringen el manejador a eventos disparados por un botón específico del ratón.

Sin embargo, ten en cuenta que los nombres de los modificadores .left, .right y .middle se basan en la disposición típica del ratón para diestros, pero en realidad representan los disparadores de eventos de "main", "secondary" y "auxiliary" del dispositivo señalador, respectivamente, y no los botones físicos reales. Así, para una disposición de ratón para zurdos, el botón "main" podría ser físicamente el derecho, pero dispararía el manejador del modificador .left. O un trackpad podría disparar el manejador .left con un toque de un dedo, el manejador .right con un toque de dos dedos y el manejador .middle con un toque de tres dedos. De manera similar, otros dispositivos y fuentes de eventos que generan eventos de "ratón" podrían tener modos de disparo que no están relacionados en absoluto con "izquierda" y "derecha".

Manejo de Eventos
FREE WEEKEND NOW LIVE!
NOW LIVE! Unlimited access to ALL Vue School courses
Join Now
02
days
:
08
hours
:
11
minutes
: