Introducción a Vue Query

En este artículo aprenderás:

  1. ¿Qué es Vue Query?
  2. Instalación y Configuración
  3. Ejemplo en un componente Vue 3
  4. Ejemplo con un Custom Hook

¿Qué es Vue Query?

Vue Query es una librería basada en react-query y utiliza todos los mismos conceptos y patrones. Nos permite manejar de manera sencilla y eficiente las peticiones asíncronas en nuestra aplicación. Por detrás esta librería se encarga de manejar el estado de nuestras peticiones, de manera que no tengamos que preocuparnos por eso cuando planeamos la estructura de nuestros componentes. Además, nos permite manejar de manera sencilla el caché de nuestras peticiones para no tener que volver a hacerlas si ya las hemos hecho anteriormente.

Instalación y Configuración

  1. Instalar la librería es muy sencillo, solo debemos ejecutar el siguiente comando:
npm install @tanstack/vue-query
  1. Utilizar el plugin de Vue Query en nuestra aplicación. Esto envolverá toda nuestra aplicación con el contexto de Vue Query.
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { VueQueryPlugin } from "@tanstack/vue-query";

createApp(App).use(VueQueryPlugin).mount("#app");
  1. Comenzar a utilizarlo! 🎉

Ejemplo en un componente Vue 3

Para utilizar Vue Query en un componente, debemos importar la función useQuery de Vue Query. Esta función nos permite manejar el estado de nuestra petición asíncrona. Vue query regresa muchos objetos dentro de los cuales están:

  1. data: El resultado de nuestra petición asíncrona. Por defecto regresa como undefined hasta que se resuelve la petición.
  2. isLoading: Un booleano que nos indica si la petición se está ejecutando o no.
  3. error: Un objeto que contiene el error de nuestra petición asíncrona en caso de que alguno ocurra.

El hook useQuery recibe dos parámetros:

  1. El nombre (o la llave única) de la petición dentro de llaves ('[]'). Este nombre es único y nos permite manejar el caché de nuestras peticiones. Si necesitamos refrescar, invalidar o limpiar el caché de una petición, podemos hacerlo utilizando este nombre.
  2. Una función que regresa la petición asíncrona. Esta función puede ser una promesa o una función asíncrona.
<script setup lang="ts">
  import { useQuery } from "@tanstack/vue-query";

  function fetchPosts() {
    return fetch("https://jsonplaceholder.typicode.com/posts").then((res) =>
      res.json()
    );
  }

  const { data, isLoading, error } = useQuery(["posts"], fetchPosts);
</script>
<template>
  <div>
    <h1>Posts</h1>
    <div v-if="isLoading">Loading...</div>
    <div v-else-if="error">Error: {{ error }}</div>
    <div v-else-if="data">
      <ul>
        <li v-for="post in data" :key="post.id">{{ post.title }}</li>
      </ul>
    </div>
  </div>
</template>

Ejemplo con Hooks Personalizados

A medida que nuestros componentes se vuelven más complejos, nos podemos ver en la necesidad de crear nuestros propios hooks para simplificar la lógica dentro del componente. Vue Query nos permite crear nuestros propios hooks personalizados para poder reutilizarlos en diferentes partes de nuestra aplicación.

// usePosts.ts
import { useQuery } from "@tanstack/vue-query";

export const usePosts = () => {
  function fetchPosts() {
    return fetch("https://jsonplaceholder.typicode.com/posts").then((res) =>
      res.json()
    );
  }

  const { data, isLoading, error } = useQuery(["posts"], fetchPosts);

  return { posts: data, postsLoading: isLoading, postsError: error };
};

Este hook ahora lo podemos utilizar en cualquier lugar de nuestra aplicación y debido a que tiene una llave única (posts), podemos refresh, invalidate o limpiar el caché de esta petición en cualquier parte de nuestra aplicación.

<script setup lang="ts">
  import { usePosts } from "./hooks/usePosts";

  const { posts, postsLoading, postsError } = usePosts();
</script>
<template>
  <div>
    <h1>Posts</h1>
    <div v-if="postsLoading">Loading...</div>
    <div v-else-if="postsError">Error: {{ postsError }}</div>
    <div v-else-if="posts">
      <ul>
        <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
      </ul>
    </div>
  </div>
</template>

Ayúdame a mejorar este artículo

¿Quisieras complementar este artículo o encontraste algún error?¡Excelente! Envíame un correo.

  • seb@sebastianfdz.com