Introducción a Vue 3

Que es Vue 3

Esta nueva versión de Vue y que actualmente se encuentra en su versión 3.2.33, fue lanzada en septiembre de 2020 y ofrece una serie de mejoras y características nuevas en comparación con versiones anteriores.

Una de las principales ventajas de Vue 3 es que es más ligero y rápido que versiones anteriores, lo que permite que las aplicaciones desarrolladas con Vue 3 carguen más rápido y se ejecuten de manera más eficiente en dispositivos móviles y de escritorio.

Otra de las mejoras importantes en Vue 3 es la introducción de la arquitectura Composition API, que permite a los desarrolladores escribir componentes de Vue de manera más clara y organizada. Esto hace que sea más fácil mantener y ampliar las aplicaciones desarrolladas con Vue 3 a medida que crecen en tamaño y complejidad.

Además, Vue 3 también incluye un nuevo sistema de ruteo y un administrador de paquetes más robusto, lo que facilita el desarrollo de aplicaciones de una sola página (SPA) y la creación de aplicaciones de escala más grande.

Si bien Vue 3 es una actualización importante en comparación con versiones anteriores, es compatible con versiones anteriores, lo que significa que los desarrolladores pueden actualizar sus aplicaciones existentes a Vue 3 sin tener que reescribir su código desde cero.

Mejoras en la composition API

Tanto si tenemos un proyecto iniciado como si lo vamos hacer desde cero usando Vue 2 (options API), en ambos casos podremos usar la composition API instalando la siguiente dependencia:

NPM: npm i @vue/composition-api

YARN: yarn add @vue/composition-api

Para comprender las mejoras que ofrece la composition API vamos a ver las novedades, los cambios importantes y algunas recomendaciones.

Novedades

  • Composition API: Con esta nueva feature podemos crear un componente utilizando funciones importadas (Vue 3) en lugar de opciones (options API en Vue 2).
  • SFC Composition API: Se añade <script setup> para usar la composition API dentro de los  componentes de archivo único (SFC).
  • Teleport: Es un nuevo componente que nos permite mover (teletransportar) parte del template de un componente a otra parte del DOM que este fuera del propio componente.
  • Fragments: Con esta nueva características podemos tener componentes con múltiples nodos en la raiz.
    • VUE 2:
      <template>
        <div> <!-- SOLO UN NODO EN LA RAIZ -->
          <header>...</header>
          <main>...</main>
          <footer>...</footer>
        </div>
      </template>
      
      VUE 3:
      <template>
        <!-- MULTIPLES NODOS EN LA RAIZ -->
        <header>...</header>
        <main v-bind="$attrs">...</main>
        <footer>...</footer>
      </template>
  • Variables CSS controladas por el estado de SFC: Ahora podemos usar v-bind dentro de la etiqueta <style>.
    • <script setup>
      const theme = {
        color: 'red'
      }
      </script>
      
      <template>
        <p>hello</p>
      </template>
      
      <style scoped>
      p {
        color: v-bind('theme.color');
      }
      </style>

Cambios importantes (Rompe de Vue 2 a Vue 3).

Habíamos comentado al comienzo del artículo que la versión 3 es aditiva sobre la versión 2, pero existen ciertos cambios que generan algunas incompatibilidades respecto a la versión 2 y que puedes consultar desde aquí.

Recomendaciones para crear proyectos en Vue 3.

Con esta nueva versión de Vue se han añadido nuevas mejoras y por lo tanto las recomendaciones por defecto que deberíamos usar en Vue 3 también han cambiado.

  • Nuevas versiones de Router, Devtools y testing
  • Creación de proyectos: Vue CLI por Vite
  • Gestión de estado: Vuex por Pinia
  • Soporte para el IDE: Vetur por Volar
  • Soporte Typescript en el CLI: vue-tsc
  • SSG: VuePress por VitePress
  • JSX: @vue/babel-preset-jsx por @vue/babel-plugin-jsx

Empezando con el código

A continuación añadiremos una aplicación muy pequeña hecha en Vue 2 y Vue 3 de dos formas diferentes.

Vue 2

<template>
  <div class="app">
    <h1>{{ message }}</h1>
    <button @click="incrementCounter">Incrementar contador</button>
    <p>Contador: {{ counter }}</p>
    <p>Contador doble: {{ doubleCounter }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hola mundo!",
      counter: 0,
    };
  },
  computed: {
    doubleCounter() {
      return this.counter * 2;
    },
  },
  methods: {
    incrementCounter() {
      this.counter++;
    },
  },
  mounted() {
    console.log("La aplicación ha sido montada");
  },
};
</script>

Vue 3

<template>
  <div class="app">
    <h1>{{ message }}</h1>
    <button @click="incrementCounter">Incrementar contador</button>
    <p>Contador: {{ counter }}</p>
    <p>Contador doble: {{ doubleCounter }}</p>
  </div>
</template>

<script>
import { ref, computed, onMounted } from "vue";

export default {
  setup() {
    const message = ref("Hola mundo!");
    const counter = ref(0);
    const incrementCounter = () => {
      counter.value++;
    };
    const doubleCounter = computed(() => {
      return counter.value * 2;
    });
    onMounted(() => {
      console.log("La aplicación ha sido montada");
    });
    return {
      message,
      counter,
      incrementCounter,
      doubleCounter,
    };
  },
};
</script>

Vue 3 con la última feature añadiendo setup en el script

<template>
  <div class="app">
    <h1>{{ message }}</h1>
    <button @click="incrementCounter">Incrementar contador</button>
    <p>Contador: {{ counter }}</p>
    <p>Contador doble: {{ doubleCounter }}</p>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
const message = ref("Hola mundo!");
const counter = ref(0);
const incrementCounter = () => {
  counter.value++;
};
const doubleCounter = computed(() => {
  return counter.value * 2;
});
onMounted(() => {
  console.log("La aplicación ha sido montada");
});
</script>

Conclusión

Como hemos podido ver en los ejemplos anteriores, el código en Vue 2 al trabajar con las options API tenemos muy bien definidas, pero esa misma ventaja acaba siendo su punto debil, ya que podemos acabar con decenas y decenas de líneas de código, mezclando todo.

Esta claro que aplicando buenas practicas en el momento de codificar podemos solucionar algunos problemas, pero seguiremos limitados a lo que ofrece Vue 2.

Por el contrario con Vue 3, usando ambas formas tenemos mayor libertad para hacer las cosas,  ya que es mucho mas cercano a Javascript y por ende a la forma de como se desarrolla tanto en React como en Svelte.

Pero no todo iban a ser buenas noticias en Vue 3, ya que esa misma libertad se acaba convirtiendo en su punto débil, ya que podemos caer en la trampa del «aquí todo vale y todo funciona», y acabar teniendo un Frankenstein de aplicación.