Last active
February 26, 2024 18:20
-
-
Save wobsoriano/9a7de2d2aaf9448c2fb952d2746b6907 to your computer and use it in GitHub Desktop.
TanStack Query + Vue Options API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { defineComponent, toRaw } from 'vue' | |
import { | |
QueryObserver, | |
type QueryKey, | |
type QueryObserverResult, | |
type QueryClient, | |
} from '@tanstack/query-core' | |
type Todo = { | |
userId: number | |
id: number | |
title: string | |
completed: boolean | |
} | |
export default defineComponent({ | |
inject: ['queryClient'], | |
data: () => ({ | |
todoId: 1, | |
result: {} as QueryObserverResult<Todo, unknown>, | |
observer: null as null | QueryObserver<Todo, unknown, Todo, Todo, QueryKey>, | |
unsubscribe: () => {} | |
}), | |
methods: { | |
async fetchTodo(id: number) { | |
const resp = await fetch('https://jsonplaceholder.typicode.com/todos/' + id) | |
const data = await resp.json() | |
return data | |
}, | |
}, | |
mounted() { | |
this.observer = new QueryObserver<Todo, unknown, Todo, Todo, QueryKey>(this.queryClient as QueryClient, { | |
queryKey: ['todo', 1], | |
queryFn: () => this.fetchTodo(1), | |
}) | |
this.unsubscribe = this.observer.subscribe((result) => { | |
Object.keys(result).forEach((key) => { | |
// @ts-expect-error: Incompatible types | |
this.result[key] = result[key] | |
}) | |
}) | |
}, | |
beforeUnmount() { | |
this.unsubscribe() | |
}, | |
watch: { | |
todoId(id) { | |
toRaw(this.observer)?.setOptions({ | |
queryKey: ['todo', id], | |
queryFn: () => this.fetchTodo(id), | |
}) | |
} | |
} | |
}) | |
</script> | |
<template> | |
<main> | |
<div v-if="result.isLoading">Loading...</div> | |
<div v-else>{{ JSON.stringify(result.data) }}</div> | |
<button @click="todoId++" :disabled="result.isLoading"> | |
{{ result.isLoading ? 'Fetching...' : 'Next todo' }} | |
</button> | |
</main> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createApp } from 'vue' | |
import App from './App.vue' | |
import { QueryClient } from '@tanstack/query-core' | |
const app = createApp(App) | |
const queryClient = new QueryClient() | |
app.provide('queryClient', queryClient) | |
app.mount('#app') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oh word I'm actually writing this using a class based approach using
vue-facing-decorator
that doesn't support the dynamic nature of updating the queryKey sadly. would you update the gist though just asking?Thanks seeing it now!