Skip to content

Manejando Eventos

Escuchando Eventos

Podemos utilizar la directiva v-on, que normalmente acortamos con el símbolo @, para escuchar los eventos del DOM y ejecutar JavaScript cuando se activen. 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 se active el evento (similar al atributo nativo onclick).

  2. Manejadores de métodos: 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 suelen utilizarse en casos sencillos, por ejemplo:

js
const count = ref(0)
js
data() {
  return {
    count: 0
  }
}
template
<button @click="count++">Añadir 1</button>
<p>El Contador está en: {{ count }}</p>

Manejadores de Métodos

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

Por ejemplo:

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

function greet(event) {
  alert(`Hola ${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">Saluda</button>

Un manejador de método recibe automáticamente el objeto Evento nativo del DOM que lo desencadena. En el ejemplo anterior, podemos acceder al elemento que envía el evento a través de event.target.tagName.

Método vs. la Detección en Línea

El compilador de plantillas detecta los manejadores de métodos comprobando si la cadena de valores v-on es un identificador 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étodos, mientras que foo() y count++ se tratan como manejadores en línea.

Llamando Métodos en Manejadores en Línea

En lugar de vincularlos directamente a un nombre de un método, también podemos llamar a los métodos en un manejador en línea. Esto nos permite pasar los argumentos personalizados del 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>

Acceso al Argumento del Evento en los Manejadores en Línea

A veces también necesitamos acceder al evento original del DOM 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
<!-- utilizando la variable especial $event -->
<button @click="warn('Aún no se puede enviar el formulario.', $event)">
  Enviar
</button>

<!-- utilizando la función de flecha en línea -->
<button @click="(event) => warn('Aún no se puede enviar el formulario.', 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 Eventos

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 pueden ser puramente sobre la lógica de los datos en lugar de tener que lidiar con los detalles de los eventos del DOM.

Para solucionar este problema, Vue proporciona modificadores de eventos para v-on. Recordemos que los modificadores son directivas postfijas denotadas por un punto.

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

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

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

<!-- sólo el modificador -->
<form @submit.prevent></form>

<!-- sólo activar el manejador si event.target es del propio elemento -->
<!-- es decir, no de un elemento hijo -->
<div @click.self="doThat">...</div>

TIP

El orden importa cuando se utilizan modificadores porque el código relevante se genera en el mismo orden. Por lo tanto, el uso de @click.prevent.self impedirá la acción por defecto de los clics en el propio elemento y sus hijos mientras que @click.self.prevent sólo impedirá la acción por defecto de los clics en el propio elemento.

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

template
<!-- utiliza el modo de captura al añadir el receptor de eventos -->
<!-- es decir, un evento dirigido a un elemento interior es manejado aquí antes de ser manejado por 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 scroll (desplazamiento)  -->
<!-- se producirá inmediatamente, en lugar de esperar a que `onScroll` -->
<!-- se complete en caso de que contenga `event.preventDefault()`.     -->
<div @scroll.passive="onScroll">...</div>

El modificador .passive se suele utilizar con los escuchadores de eventos táctiles para mejorar el rendimiento en los dispositivos móviles.

TIP

No utilice .passive y .prevent juntos, porque .passive ya le indica al navegador que no pretendes impedir el comportamiento por defecto del evento, y es probable que veas una advertencia del navegador si lo haces.

Modificadores Clave

Cuando escuchamos eventos de teclado, a menudo necesitamos comprobar teclas específicas. Vue permite añadir modificadores de tecla para v-on o @ al escuchar eventos de teclado:

template
<!-- sólo llama a `submit` cuando la `key` es `Enter` -->
<input @keyup.enter="submit" />

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

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

En el ejemplo anterior, el controlador sólo será llamado si $event.key es igual a 'PageDown'.

Alias de las Teclas

Vue proporciona alias para las teclas más utilizadas:

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

Teclas Modificadoras del Sistema

Puedes utilizar los siguientes modificadores para activar los receptores de eventos del ratón o del teclado sólo cuando se pulse la tecla modificadora correspondiente:

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

Note

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

Por ejemplo:

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

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

TIP

Ten en cuenta que las teclas modificadoras son diferentes de las teclas normales y cuando se usan con eventos keyup, tienen que estar pulsadas cuando se emite el evento. En otras palabras, keyup.ctrl sólo se activará si sueltas una tecla mientras mantienes pulsada ctrl. No se activará si sueltas la tecla "ctrl" sola.

Modificador .exact

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

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

<!-- esto sólo se disparará cuando se pulse Ctrl y ninguna otra tecla -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- esto sólo se disparará cuando no se pulsen modificadores del sistema -->
<button @click.exact="onClick">A</button>

Modificadores del Botón del Ratón

  • .left
  • .right
  • .middle

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

Manejando Eventos has loaded