Mastering TanStack Query in Vue: The Ultimate Guide (2025)

Approx Time: 6 Minutes

Rishabh Pandey • January 5, 2025

vue

Introduction

If you're working with Vue and need an efficient way to fetch, cache, and synchronize data with your UI, TanStack Query in Vue (formerly React Query) is a game-changer. Handling API calls manually can be a pain—managing loading states, caching, refetching, and error handling all require extra code. TanStack Query for Vue simplifies all of this, making data fetching seamless and improving performance.

This guide will walk you through everything you need to know about TanStack Query in Vue, from installation and fundamental concepts to advanced features like caching, pagination, optimistic updates, and background refetching. We'll also look under the hood to understand how TanStack Query works internally and provide a complete example at the end.

By the time you're done, you'll have a strong understanding of how to implement TanStack Query in Vue to optimize your app’s API calls.


Why Use TanStack Query for Vue?

Problems with Traditional API Fetching in Vue

When fetching data in Vue using fetch() or axios, developers often face the following challenges:

How TanStack Query Solves These Problems

TanStack Query takes care of all these challenges out of the box, providing:

Automatic Caching – No redundant API calls; data is stored and reused efficiently.

Stale Data Management – Automatically invalidates and refreshes outdated data.

Background Refetching – Ensures users always see the latest information.

Error Handling & Auto Retries – Retries failed requests automatically for better resilience.

Optimistic Updates – Instantly updates UI before the server confirms changes.

Pagination & Infinite Queries – Makes handling paginated APIs a breeze.

Works with Vue’s Composition API – Fully reactive and integrates seamlessly into Vue 3.


Installation and Setup

Installing TanStack Query for Vue

First, install the TanStack Query package for Vue:

npm install @tanstack/vue-query

or if you're using Yarn:

yarn add @tanstack/vue-query

Setting Up the Query Client

To enable TanStack Query throughout your Vue app, configure a QueryClient and register it as a plugin in main.js (or main.ts for TypeScript users):

import { createApp } from 'vue';
import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query';
import App from './App.vue';

// Create a QueryClient instance
const queryClient = new QueryClient();

const app = createApp(App);
app.use(VueQueryPlugin, { queryClient });
app.mount('#app');

This makes the QueryClient globally available, so you can use it anywhere in your app.


How TanStack Query Works Under the Hood

To better understand TanStack Query, let's break down its core concepts and internal workings:

1. QueryClient: The Brain of TanStack Query

2. Query Keys: Unique Identifiers for Queries

Every query needs a query key, which acts as an identifier for caching and refetching purposes. Example:

const { data, error, isLoading } = useQuery(['users'], fetchUsers);

3. Caching & Stale Time

TanStack Query caches responses automatically. You can control how long data stays fresh before becoming stale:

const { data } = useQuery(['users'], fetchUsers, {
  staleTime: 60000, // Data is fresh for 60 seconds
});

4. Background Refetching

By default, TanStack Query refetches data whenever the browser window is refocused. You can disable this behavior if needed:

const { data } = useQuery(['users'], fetchUsers, {
  refetchOnWindowFocus: false,
});

Fetching Data with useQuery

Now, let’s fetch some data using useQuery:

import { useQuery } from '@tanstack/vue-query';
import axios from 'axios';

const fetchUsers = async () => {
  const { data } = await axios.get('https://jsonplaceholder.typicode.com/users');
  return data;
};

export default {
  setup() {
    const { data, error, isLoading } = useQuery(['users'], fetchUsers);
    return { data, error, isLoading };
  },
};

Mutating Data with useMutation

If you need to add, update, or delete data, use useMutation:

import { useMutation, useQueryClient } from '@tanstack/vue-query';
import axios from 'axios';

const addUser = async (user) => {
  const { data } = await axios.post('https://jsonplaceholder.typicode.com/users', user);
  return data;
};

export default {
  setup() {
    const queryClient = useQueryClient();
    const mutation = useMutation(addUser, {
      onSuccess: () => {
        queryClient.invalidateQueries(['users']);
      },
    });

    return { mutation };
  },
};

Example: User Management App

Here’s a full example combining useQuery and useMutation:

<template>
  <div>
    <h1>Users</h1>
    <ul>
      <li v-for="user in data" :key="user.id">{{ user.name }}</li>
    </ul>
    <button @click="addUser">Add Random User</button>
  </div>
</template>

<script setup>
import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query';
import axios from 'axios';

const fetchUsers = async () => {
  const { data } = await axios.get('https://jsonplaceholder.typicode.com/users');
  return data;
};

const { data } = useQuery(['users'], fetchUsers);
const queryClient = useQueryClient();

const mutation = useMutation(async () => {
  return axios.post('https://jsonplaceholder.typicode.com/users', { name: `User ${Math.random()}` });
}, {
  onSuccess: () => queryClient.invalidateQueries(['users']),
});

const addUser = () => mutation.mutate();
</script>

Conclusion

TanStack Query in Vue simplifies API calls, improves performance, and reduces boilerplate code. Whether you’re fetching, mutating, or caching data, TanStack Query makes Vue development easier.

Try implementing it in your next Vue project and enjoy the benefits of effortless data fetching! 🚀

Share on Twitter