Skip to content

Commit d27d931

Browse files
feat: provide instance of QueryClient to provider and change default key (#65)
* feat(hooks): provide instance of QueryClient to provider and change default key * ci: bump codecov action * feat(devtools): support multiple clients * docs: multi-client example * docs: multi-client guide page * test: improve coverage
1 parent 5546c91 commit d27d931

33 files changed

+465
-57
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
env:
4040
CI: true
4141
- name: Upload coverage to Codecov
42-
uses: codecov/codecov-action@v1
42+
uses: codecov/codecov-action@v2
4343
with:
4444
token: ${{ secrets.CODECOV_TOKEN }}
4545

docs/_sidebar.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@
2020
- [Queries](guides/queries.md)
2121
- [Query Keys](guides/query-keys.md)
2222
- [Query Functions](guides/query-functions.md)
23+
- [Custom clients (experimental)](guides/custom-clients.md)
2324
- [SSR & Nuxt.js (experimental)](guides/ssr.md)

docs/guides/custom-clients.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
### Custom client
2+
3+
Vue Query allows providing custom `QueryClient` for Vue context.
4+
5+
It might be handy when you need to create `QueryClient` beforehand to integrate it with other libraries that do not have access to the Vue context.
6+
7+
For this reason, `useQueryProvider` accepts either QueryClient options or `QueryClient` as a first argument.
8+
9+
If You provide QueryClient options, `QueryClient` instance will be created internally and provided to Vue context.
10+
11+
```js
12+
useQueryProvider(queryClientOptions);
13+
```
14+
15+
```js
16+
const myClient = new QueryClient(queryClientOptions);
17+
useQueryProvider(myClient);
18+
```
19+
20+
### Custom context keys
21+
22+
You can also customize the key under which `QueryClient` will be accessible in Vue context. This can be usefull is you want to avoid name clashing between multiple apps on the same page.
23+
24+
It works both with default, and custom provided `QueryClient`
25+
26+
```js
27+
useQueryProvider(queryClientOptions, "foo");
28+
```
29+
30+
```js
31+
const myClient = new QueryClient(queryClientOptions);
32+
useQueryProvider(myClient, "bar");
33+
```
34+
35+
To use the custom client key, You have to provide it as a query options
36+
37+
```js
38+
useQuery("query1", fetcher, { queryClientKey: "foo" });
39+
```
40+
41+
Devtools also support this by the `queryClientKeys` prop. You can provide multiple keys and switch between them to monitor multiple clients.
42+
43+
```vue
44+
<template>
45+
<VueQueryDevTools :queryClientKeys="['foo', 'bar']" />
46+
</template>
47+
```
48+
49+
Internally custom key will be combined with default query key as a suffix. But user do not have to worry about it.
50+
51+
```js
52+
useQueryProvider(queryClientOptions, "foo"); // -> VUE_QUERY_CLIENT:foo
53+
```

examples/multi-client/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local
6+
package-lock.json

examples/multi-client/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Basic example
2+
3+
To run this example:
4+
5+
- `npm install` or `yarn`
6+
- `npm run dev` or `yarn dev`

examples/multi-client/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Vue Query Example</title>
7+
</head>
8+
<body>
9+
<div id="app"></div>
10+
<script type="module" src="/src/main.ts"></script>
11+
</body>
12+
</html>

examples/multi-client/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"dev": "vite",
5+
"build": "vite build",
6+
"build:dev": "vite build -m development",
7+
"serve": "vite preview"
8+
},
9+
"dependencies": {
10+
"vue": "^3.0.5",
11+
"vue-query": ">=1.0.0"
12+
},
13+
"devDependencies": {
14+
"@vitejs/plugin-vue": "^1.1.5",
15+
"@vue/compiler-sfc": "^3.0.5",
16+
"typescript": "^4.1.3",
17+
"vite": "^2.0.5"
18+
}
19+
}

examples/multi-client/src/App.vue

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script lang="ts">
2+
import { defineComponent } from "vue";
3+
import { useQueryProvider, QueryClient } from "vue-query";
4+
import { VueQueryDevTools } from "vue-query/devtools";
5+
6+
import Todos from "./Todos.vue";
7+
8+
export default defineComponent({
9+
name: "App",
10+
components: { Todos, VueQueryDevTools },
11+
setup() {
12+
const myClient = new QueryClient();
13+
useQueryProvider();
14+
useQueryProvider({}, "Foo");
15+
useQueryProvider(myClient, "Bar");
16+
},
17+
});
18+
</script>
19+
20+
<template>
21+
<h1>Vue Query - Multi Client</h1>
22+
<Todos />
23+
<VueQueryDevTools :initialIsOpen="true" :queryClientKeys="['Foo', 'Bar']" />
24+
</template>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script lang="ts">
2+
import { defineComponent } from "vue";
3+
import { useQuery } from "vue-query";
4+
5+
interface Todo {
6+
userId: number;
7+
id: number;
8+
title: string;
9+
completed: boolean;
10+
}
11+
12+
const fetcher = async (): Promise<Todo[]> =>
13+
await fetch("https://jsonplaceholder.typicode.com/todos").then((response) =>
14+
response.json()
15+
);
16+
17+
export default defineComponent({
18+
name: "Todos",
19+
setup() {
20+
const { isLoading, isError, isFetching, data, error, refetch } = useQuery(
21+
"todos",
22+
fetcher
23+
);
24+
25+
useQuery("todos2", fetcher, { queryClientKey: "Foo" });
26+
useQuery("todos3", fetcher, { queryClientKey: "Bar" });
27+
28+
return { isLoading, isError, isFetching, data, error, refetch };
29+
},
30+
});
31+
</script>
32+
33+
<template>
34+
<p>Turn on <b>network throttling</b> in dev-tools and press Refetch</p>
35+
<button @click="refetch" :disabled="isFetching">
36+
{{ isFetching ? "Refetching..." : "Refetch" }}
37+
</button>
38+
<h2>TODO list</h2>
39+
<div v-if="isLoading">Loading...</div>
40+
<div v-else-if="isError">An error has occurred: {{ error }}</div>
41+
<div v-else-if="data">
42+
<ul>
43+
<li v-for="item in data" :key="item.id">
44+
{{ item.completed ? "🗹" : "☐" }} {{ item.title }}
45+
</li>
46+
</ul>
47+
</div>
48+
</template>
49+
50+
<style>
51+
ul {
52+
list-style: none;
53+
}
54+
</style>

examples/multi-client/src/main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { createApp } from "vue";
2+
3+
import App from "./App.vue";
4+
5+
createApp(App).mount("#app");

0 commit comments

Comments
 (0)