Composition API (Vue 3)

En Vue 3 se introduce la Composition API, una nueva forma alternativa de escribir código en Vue. Dependiendo de la versión de Vue que estemos utilizando, podremos escribir código Vue utilizando una u otra API:

  • En Vue 2 sólo se dispone de la Options API.
  • En Vue 3 podemos elegir entre seguir usando la Options API o usar la Composition API

La Composition API está diseñada para mejorar sustancialmente la capacidad de crecimiento de un proyecto, así como facilitar la reutilización de componentes.

Options API vs Composition API

La modalidad Options API nos permite trabajar mediante opciones en un objeto de Vue. La información está separada por nombre de estructuras, de modo que la curva de aprendizaje es muy sencilla y agradable, y resulta muy apropiado para usuarios que comienzan a trabajar con frameworks:

export default {
  name: "ComponentName",
  props: { ... },     // Props
  data() { ... },     // Data variables
  computed: { ... },  // Computed props
  methods: { ... },   // Functions
  mounted() { ... }   // Mounted hook (lifecycle)
}

Por otro lado, la Composition API, en lugar de separar la información en opciones, utiliza un método especial (hook) llamado setup() donde podremos escribir nuestro código Javascript de inicialización del componente. Dicho hook devolverá un con los elementos que queramos utilizar en el resto del componente (como por ejemplo, en el <template>).

La forma de trabajar con esta Composition API es más cercana a Javascript nativo (y puede que un poco más complejo si no se tienen bases sólidas de Javascript), pero es mucho más práctica para reutilizar datos y crear aplicaciones grandes y fáciles de mantener.

Por esta razón, puede ser una buena aproximación para usuarios avanzados que ya han trabajado previamente con Vue y quieren optar por utilizar una forma más avanzada de gestionar los componentes de su aplicación Vue. La sintaxis de dicha API es la siguiente:

export default {
  name: "ComponentName",
  props: { ... },     // Props
  setup() {
    // Init logic, lifecycle hooks, etc...
    return {
      // Data, methods, computed, etc...
    }
  }
}

Vamos a analizar los cambios de esta Composition API respecto a la anterior Options API, y a profundizar en las nuevas características que añade.

Preparación (setup)

En primer lugar, el cambio más destacable que observaremos es el hook denominado setup(), que es el que se encargará de dispararse en la fase de inicialización del componente (algo así como el constructor del componente). Equivale a la antigua fase del ciclo de vida denominada created, que deja de existir en Vue 3.

En su lugar, utilizaremos este hook, que tendrá dos parámetros opcionales: props y context:

  • props es un (realmente un Proxy) con las props que hayan sido debidamente inicializadas y definidas en el componente (de la forma clásica).

  • context es un que contendrá (como su nombre indica) el contexto del componente, con detalles interesantes como attrs, emit o slots, que veremos más adelante.

Veamos un fragmento de código sencillo, donde implementamos un ejemplo de setup():

<template>
  <div>{{ total }}</div>
</template>

<script>
export default {
  props: {
    price: Number
  },
  setup(props, context) {
    const total = `Total price (50% offer): ${props.price / 2}`;

    return { total }
  }
}
</script>

Como se puede ver, se mantiene la opción props para definir las props del componente, pero se añade el hook setup() para crear la lógica de inicialización del componente. De esta forma, en el interior de setup() se pasan a realizar varias operaciones principales:

Tareas de inicialización o ciclo de vida: Tareas de preparación que deben hacerse antes de iniciar el componente, que antiguamente se realizaban en created(). También otras tareas realizadas en mounted()o updated() son ahora definidas en esta función.

Tareas de definición: Tanto las variables que antes establecíamos en data, las funciones de methods, las propiedades computadas de computed o los watchers de watch pasan a ser variables o funciones de Vue, con algunos cambios respecto a Vue 2.

Devolución de elementos a utilizar: Los elementos devueltos en el objeto del return de la última línea del setup() se podrán utilizar en otras zonas del componente, como en el apartado <template>.

Hooks del ciclo de vida

En Vue 3 los hooks del ciclo de vida sufren un pequeño cambio. En lugar de ser métodos que se utilizan como opciones, son funciones que se importan desde el paquete vue. Casi todos conservan el mismo nombre que en Vue 2, pero se preceden con un on en formato «camelCase». Además, se hacen algunas variaciones:

Options API (Vue 2) Options API (Vue 3) Composition API (Vue 3)
beforeCreate beforeCreate Se escribe directamente en setup().
created created Se escribe directamente en setup().
beforeMount beforeMount onBeforeMount
mounted mounted onMounted
beforeUpdate beforeUpdate onBeforeUpdate
updated updated onUpdated
beforeDestroy beforeUnmount onBeforeUnmount
destroyed unmounted onUnmounted
activated activated onActivated
deactivated deactivated onDeactivated

Una vez importados, podemos utilizarlos en el hook setup(), pasándole por parámetro una función anónima (callback) que contendrá la lógica a ejecutar en esa fase del ciclo de vida. Si tienes más dudas, echa un vistazo al ciclo de vida de Vue, en caso contrario, observa el siguiente ejemplo para comprender como funcionan los ciclos de vida en Vue 3:

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

export default {
  props: {
    price: Number
  },
  setup(props, context) {
    const total = `Total: ${props.price * 2}`;

    /* Formato corto */
    onMounted(() => console.log("mounted!"));

    /* Formato largo */
    onBeforeMount(() => {
      console.log("beforeMount hook!");
    });

    return {
      total
    }
  }
}
</script>

Al margen de los hooks anteriores, en Vue 3 aparecen nuevos hooks que pueden resultarnos interesantes. Es el caso de onRenderTracked y onRenderTriggered, los cuales se disparan en fases relacionadas con la renderización visual de contenido:

Hook (Options API) Hook (Composition API) ¿Cuándo se llama?
renderTracked onRenderTracked() Dependencia reactiva accedida por primera vez (renderizado).
renderTriggered onRenderTriggered() Comienza una nueva renderización.

Además de estos detalles, en Vue 3 la API de Reactividad de Vue cambia considerablemente, modificando la forma de crear variables reactivas, propiedades computadas o similares. En el siguiente artículo veremos algunos de esos cambios.

Manz
Publicado por Manz

Docente, divulgador informático y freelance. Autor de Emezeta.com, es profesor en la Universidad de La Laguna y dirige el curso de Programación web FullStack y Diseño web FrontEnd de EOI en Tenerife (Canarias). En sus ratos libres, busca GIF de gatos en Internet.