Por: Juan Andrés Núñez
Juan Andrés Núñez - juanwmedia

Especialista en tecnologías Web. Me dedico a enseñar desarrollo Web moderno a cualquier persona (físicamente en clase y a través de Internet) desde una perspectiva holística: teniendo en cuenta las competencias técnicas necesarias, junto a las habilidades personales o soft skills. Tienes más información en mi Web.

  • Una de las novedades más llamativas de Vue 3 es la posibilidad de usar argumentos en la directiva v-model, permitiendo entonces el utilizar múltiples v-model en componentes, cada uno asociado una propiedad reactiva. Vamos a ponerlo en práctica 🔥 en esta lección.
  • He creado un pequeño proyecto basado en Vue 3 usando Vite (lo vimos en la lección anterior). Cuento con un componente llamado PersonalForm.vue ya creado y como ves se trata de un sencillo formulario con tres inputs.
  • En el modelo local de App.vue tenemos tres propiedades que quiero pasarle al componente y permitir que este las manipule con data binding en los dos sentidos.
  • Es decir, quiero mantener el estado entre la vista principal y un componente. Algo muy común.
  • Como primer impulso querrás usar v-model, pero recuerda que es un atajo para combinar :value e @input, así que vamos a usarlos directamente y luego lo resolveremos con Vue 3 y su Composition API.
  • Primero tendremos que pasar al componente una propiedad por cada propiedad del modelo.
<PersonalForm :name="name" :age="age" :color="color" />
  • Ahora tendremos que declarar las propiedades en el componente y asociarlas a cada input con :value.
...
props: ["name", "age", "color"],
...
<input
  :value="name"
  type="text"
  id="name"
  placeholder="Insert your name"
/>
...
  • Comprobamos que funciona. El siguiente paso lógico es emitir eventos cada vez que se recibe un evento input en cada uno de los elementos del formulario. Además debemos pasar como parámetro el nuevo contenido.
<input
  :value="name"
    @input="(event) => $emit('update:name', event.target.value)"
    ...
/>
  • Nos queda ahora recibir el evento emitido en cada input y responder al mismo lanzando un método local que actualice las propiedades del modelo.
<PersonalForm
  :name="name"
  :age="age"
  :color="color"
  @update:name="updateName"
  @update:color="updateColor"
  @update:age="updateAge"
/>
...
updateName(val) {
 this.name = val;
},
  • Podemos usar el color elegido como fondo para comprobar que el binding funciona perfectamente, además de mostrar el modelo en el propio template.
<article :style="{ backgroundColor: color }"></article>
...
<pre>{{ $data }}</pre>
  • Y ya lo tendríamos listo. Fíjate que hemos tenido que escuchar cada evento y crear un método para aplicar los cambios. No hay nada malo en ello, pero ahora comprobarás como con Vue 3 y sus múltiples v-model, esto se convierte en algo sensiblemente más sencillo.
  • No tenemos que cambiar ni una compa en nuestro componente PersonalForm.vue, todo lo haremos en App.vue.
  • No necesitamos los event listeners del componente ni los métodos locales, por lo que los podemos comentar/eliminar.
  • Y ahora, tal como pone en la documentación, podemos usar tres instancias de v-model donde estamos instanciando a su vez nuestro componente. Cada una de ellas se dirige a una propiedad en concreto
<PersonalForm
  v-model:name="name"
  v-model:age="age"
  v-model:color="color"
/>
  • De esta forma estamos a la vez declarando las propiedades y escuchando sus cambios. Igual que hacíamos antes.
  • Ojo ⚠️: es importante que los nombres de los eventos que emitamos sigan el patrón update:propName para que esto funcione. Nosotros ya lo teníamos así desde el principio.
  • Podemos comprobar que sigue funcionando. Para finalizar usemos la Composition API en la instancia principal. En lugar de data() pasemos a usar el nuevo setup().
import { ref } from 'vue'
...
setup() {
  const name = ref("John Doe");
  const age = ref(33);
  const color = ref("#FF0000");
  return {
    name, age, color
  }
}
  • Una vez más, todo funciona correctamente.

No te pierdas ninguna novedad

Escuela Vue en Twitter

Participa en la Comunidad Escuela Vue

Comunidad Escuela Vue