From ed9b7ea553f34899dd827d678817b7d843cefbd0 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Tue, 22 Nov 2022 16:56:51 +0330 Subject: [PATCH 01/24] feat: `useNuxtData` composable --- packages/nuxt/src/app/composables/asyncData.ts | 5 +++++ packages/nuxt/src/app/composables/index.ts | 2 +- packages/nuxt/src/imports/presets.ts | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index eba8f205a51..5fc84199f1b 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -268,6 +268,11 @@ export function useLazyAsyncData< return useAsyncData(key, handler, { ...options, lazy: true }, null) } +export function useNuxtData (key?: string) { + const nuxt = useNuxtApp() + return key ? nuxt.payload.data[key] : nuxt.payload.data +} + export async function refreshNuxtData (keys?: string | string[]): Promise { if (process.server) { return Promise.resolve() diff --git a/packages/nuxt/src/app/composables/index.ts b/packages/nuxt/src/app/composables/index.ts index 251a09fd596..f7abb21e90d 100644 --- a/packages/nuxt/src/app/composables/index.ts +++ b/packages/nuxt/src/app/composables/index.ts @@ -1,5 +1,5 @@ export { defineNuxtComponent } from './component' -export { useAsyncData, useLazyAsyncData, refreshNuxtData, clearNuxtData } from './asyncData' +export { useAsyncData, useLazyAsyncData, useNuxtData, refreshNuxtData, clearNuxtData } from './asyncData' export type { AsyncDataOptions, AsyncData } from './asyncData' export { useHydration } from './hydrate' export { useState } from './state' diff --git a/packages/nuxt/src/imports/presets.ts b/packages/nuxt/src/imports/presets.ts index f8102b2a207..56fa0a18936 100644 --- a/packages/nuxt/src/imports/presets.ts +++ b/packages/nuxt/src/imports/presets.ts @@ -23,6 +23,7 @@ const appPreset = defineUnimportPreset({ imports: [ 'useAsyncData', 'useLazyAsyncData', + 'useNuxtData', 'refreshNuxtData', 'clearNuxtData', 'defineNuxtComponent', From 2957d603854bef53b8f0387612ac98f7977d5f2f Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Tue, 22 Nov 2022 18:53:50 +0330 Subject: [PATCH 02/24] change useNuxtData to return the full record --- packages/nuxt/src/app/composables/asyncData.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 5fc84199f1b..12773ef187d 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -268,9 +268,8 @@ export function useLazyAsyncData< return useAsyncData(key, handler, { ...options, lazy: true }, null) } -export function useNuxtData (key?: string) { - const nuxt = useNuxtApp() - return key ? nuxt.payload.data[key] : nuxt.payload.data +export function useNuxtData () { + return useNuxtApp().payload.data } export async function refreshNuxtData (keys?: string | string[]): Promise { From 3c17872f83f7ef5838539b6bcbe5de435958a4cf Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Tue, 22 Nov 2022 19:14:23 +0330 Subject: [PATCH 03/24] docs: initial docs --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs/content/1.docs/3.api/1.composables/use-nuxt-data.md diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md new file mode 100644 index 00000000000..7f34a639b9e --- /dev/null +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -0,0 +1,9 @@ +# `useNuxtData` + +`useNuxtData` gives you access to the cache of `useAsyncData`, `useLazyAsyncData`, `useFetch` and `useLazyFetch`. + +## Type + +```ts +useNuxtData():‌ Recod +``` \ No newline at end of file From 26ccb25c8d5e17f42f0194361fe11594b3cd89d7 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:07:00 +0330 Subject: [PATCH 04/24] docs: add the first example --- .../3.api/1.composables/use-nuxt-data.md | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 7f34a639b9e..b827bfede60 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -6,4 +6,27 @@ ```ts useNuxtData():‌ Recod -``` \ No newline at end of file +``` + +## Examples + +### Show stale data while fetching in the background +The example below shows how you can use cached data as a placeholder while the most recent data is being fetched from the server. + +```ts +// In Archive.vue +const { data } = await useFetch('/api/posts', { + key: 'posts', // You need to set a key to access the data later. +}) +``` + +```ts +// In Single.vue +const { data } = await useFetch(`/api/posts/${postId}`, { + key: `post-${postId}`, + default: () => { + // Find the individual post from the cache and set it as the default value. + return useNuxtData().posts.find(post => post.id === id) + } +}) +``` From fb4bf07f93ce549aecc0d433863e9707e2723657 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:08:31 +0330 Subject: [PATCH 05/24] fix postId --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index b827bfede60..f50e2c76b68 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -26,7 +26,7 @@ const { data } = await useFetch(`/api/posts/${postId}`, { key: `post-${postId}`, default: () => { // Find the individual post from the cache and set it as the default value. - return useNuxtData().posts.find(post => post.id === id) + return useNuxtData().posts.find(post => post.id === postId) } }) ``` From d5a914f82b3ea5908541681e14060c10e1e0fbc0 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:12:55 +0330 Subject: [PATCH 06/24] blank line after heading --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index f50e2c76b68..071470c25a0 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -11,6 +11,7 @@ useNuxtData():‌ Recod ## Examples ### Show stale data while fetching in the background + The example below shows how you can use cached data as a placeholder while the most recent data is being fetched from the server. ```ts From 50895945b851a6772a8921b3c6a644e4a031f7b2 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:54:43 +0330 Subject: [PATCH 07/24] second example in the docs --- .../3.api/1.composables/use-nuxt-data.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 071470c25a0..08534b07f3f 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -31,3 +31,33 @@ const { data } = await useFetch(`/api/posts/${postId}`, { } }) ``` + +### Optimistic Updates + +We can leverage the cache to update the UI after a mutation, while the data is being invalidated in the background. + +```ts +// In Todos.vue +const { data } = await useFetch('/api/todos', { + key: 'todos' +}) +``` + +```ts +// In AddTodo.vue +const newTodo = ref('') +const previousTodos = ref([]) + +const { data } = await useFetch('/api/addTodo', { + key: 'addTodo', + method: 'post', + onRequest () { + previousTodos.value = useNuxtData().todos // Store the previously cached value to restore if fetch fails. + + useNuxtData().todos.push(newTodo.value) // Optimistically update the todos. + }, + onRequestError () { + useNuxtData().todos = previousTodos.value // Rollback the data if the request failed. + }, +}) +``` From 35bd10394eecc00d93b255d43b07fc4d199ac447 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:57:32 +0330 Subject: [PATCH 08/24] complete the example --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 08534b07f3f..b88e83eec10 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -59,5 +59,8 @@ const { data } = await useFetch('/api/addTodo', { onRequestError () { useNuxtData().todos = previousTodos.value // Rollback the data if the request failed. }, + async onResponse () { + await refreshNuxtData('todos') // Invalidate todos in the background if the request succeeded. + } }) ``` From 1f7bd0a11de2290d234683a9d816836c904ed474 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:58:46 +0330 Subject: [PATCH 09/24] add the missing options --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index b88e83eec10..0059cb94402 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -51,6 +51,9 @@ const previousTodos = ref([]) const { data } = await useFetch('/api/addTodo', { key: 'addTodo', method: 'post', + body: { + todo: todo.value + }, onRequest () { previousTodos.value = useNuxtData().todos // Store the previously cached value to restore if fetch fails. From 141bf4f43008270f631dbad940565bce9f8630c7 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Wed, 23 Nov 2022 15:59:22 +0330 Subject: [PATCH 10/24] fix naming --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 0059cb94402..fa2597bfc13 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -52,7 +52,7 @@ const { data } = await useFetch('/api/addTodo', { key: 'addTodo', method: 'post', body: { - todo: todo.value + todo: newTodo.value }, onRequest () { previousTodos.value = useNuxtData().todos // Store the previously cached value to restore if fetch fails. From 04dcc7923b1cdbbd1e2f6c90752b960b987c53f2 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Fri, 25 Nov 2022 13:14:50 +0330 Subject: [PATCH 11/24] add optional key arg --- packages/nuxt/src/app/composables/asyncData.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 12773ef187d..a25242faa5a 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -268,8 +268,11 @@ export function useLazyAsyncData< return useAsyncData(key, handler, { ...options, lazy: true }, null) } -export function useNuxtData () { - return useNuxtApp().payload.data +export function useNuxtData (key: string): Ref +export function useNuxtData (): Record +export function useNuxtData (key?: string): unknown { + const nuxt = useNuxtApp() + return key ? ref(nuxt.payload.data[key]) : nuxt.payload.data } export async function refreshNuxtData (keys?: string | string[]): Promise { From cb6fd2227251d46055b645d069cd051177a76723 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Fri, 25 Nov 2022 13:16:31 +0330 Subject: [PATCH 12/24] update the docs --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index fa2597bfc13..a8bb644a896 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -5,6 +5,7 @@ ## Type ```ts +useNuxtData(key: string):‌ Ref useNuxtData():‌ Recod ``` @@ -27,7 +28,7 @@ const { data } = await useFetch(`/api/posts/${postId}`, { key: `post-${postId}`, default: () => { // Find the individual post from the cache and set it as the default value. - return useNuxtData().posts.find(post => post.id === postId) + return useNuxtData('posts').value.find(post => post.id === postId) } }) ``` @@ -55,12 +56,12 @@ const { data } = await useFetch('/api/addTodo', { todo: newTodo.value }, onRequest () { - previousTodos.value = useNuxtData().todos // Store the previously cached value to restore if fetch fails. + previousTodos.value = useNuxtData('todos').value // Store the previously cached value to restore if fetch fails. - useNuxtData().todos.push(newTodo.value) // Optimistically update the todos. + useNuxtData('todos').value.push(newTodo.value) // Optimistically update the todos. }, onRequestError () { - useNuxtData().todos = previousTodos.value // Rollback the data if the request failed. + useNuxtData('todos').value = previousTodos.value // Rollback the data if the request failed. }, async onResponse () { await refreshNuxtData('todos') // Invalidate todos in the background if the request succeeded. From 0ce0b392076b3028f7f28a87d2b21f2a34fcba22 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Fri, 25 Nov 2022 16:19:54 +0330 Subject: [PATCH 13/24] added generic to docs --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index a8bb644a896..7e0a44b510c 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -5,7 +5,7 @@ ## Type ```ts -useNuxtData(key: string):‌ Ref +useNuxtData (key: string): Ref useNuxtData():‌ Recod ``` From 556224911fd178be87ca0b15e6a0b089b3192983 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Mon, 28 Nov 2022 19:58:00 +0330 Subject: [PATCH 14/24] added generic to single variant --- packages/nuxt/src/app/composables/asyncData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index a25242faa5a..6ed99d2b1fd 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -268,7 +268,7 @@ export function useLazyAsyncData< return useAsyncData(key, handler, { ...options, lazy: true }, null) } -export function useNuxtData (key: string): Ref +export function useNuxtData (key: string): Ref export function useNuxtData (): Record export function useNuxtData (key?: string): unknown { const nuxt = useNuxtApp() From 31bddc8a0689ce36ebcd1712e4b37cbaf20d50aa Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Mon, 28 Nov 2022 20:03:17 +0330 Subject: [PATCH 15/24] use toRef to keep reactivity and initialize value if key doesn't exist --- packages/nuxt/src/app/composables/asyncData.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 6ed99d2b1fd..0de951b8d05 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -1,4 +1,4 @@ -import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref } from 'vue' +import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref, toRef, toRefs } from 'vue' import type { Ref, WatchSource } from 'vue' import { NuxtApp, useNuxtApp } from '../nuxt' import { createError } from './error' @@ -269,10 +269,16 @@ export function useLazyAsyncData< } export function useNuxtData (key: string): Ref -export function useNuxtData (): Record +export function useNuxtData (): Ref> export function useNuxtData (key?: string): unknown { - const nuxt = useNuxtApp() - return key ? ref(nuxt.payload.data[key]) : nuxt.payload.data + const data = useNuxtApp().payload.data + + // initialize value when key is not already set + if (key && data[key] === undefined) { + data[key] = null + } + + return key ? toRef(data, key) : toRefs(data) } export async function refreshNuxtData (keys?: string | string[]): Promise { From 29796ccec438a28bde7c009e399c629023edc4f1 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Mon, 28 Nov 2022 20:39:36 +0330 Subject: [PATCH 16/24] fixed reactivity --- packages/nuxt/src/app/composables/asyncData.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 0de951b8d05..efde465b79f 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -1,4 +1,4 @@ -import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref, toRef, toRefs } from 'vue' +import { onBeforeMount, onServerPrefetch, onUnmounted, ref, getCurrentInstance, watch, unref, toRef } from 'vue' import type { Ref, WatchSource } from 'vue' import { NuxtApp, useNuxtApp } from '../nuxt' import { createError } from './error' @@ -271,14 +271,14 @@ export function useLazyAsyncData< export function useNuxtData (key: string): Ref export function useNuxtData (): Ref> export function useNuxtData (key?: string): unknown { - const data = useNuxtApp().payload.data + const nuxt = useNuxtApp() // initialize value when key is not already set - if (key && data[key] === undefined) { - data[key] = null + if (key && nuxt.payload.data[key] === undefined) { + nuxt.payload.data[key] = null } - return key ? toRef(data, key) : toRefs(data) + return key ? toRef(nuxt.payload.data, key) : ref(nuxt.payload.data) } export async function refreshNuxtData (keys?: string | string[]): Promise { From 2f73841e9aaed9c3855b348d35daa4d69df22d89 Mon Sep 17 00:00:00 2001 From: Mahdi Boomeri Date: Mon, 28 Nov 2022 20:40:30 +0330 Subject: [PATCH 17/24] update the docs --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 7e0a44b510c..eee43a5c2ed 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -6,7 +6,7 @@ ```ts useNuxtData (key: string): Ref -useNuxtData():‌ Recod +useNuxtData():‌ Ref> ``` ## Examples From a93cb6e7115c2af3d9b24e6d4389764c395263d7 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 5 Dec 2022 11:31:46 +0000 Subject: [PATCH 18/24] chore: fix typo --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index eee43a5c2ed..ffb9bb9d7b3 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -6,7 +6,7 @@ ```ts useNuxtData (key: string): Ref -useNuxtData():‌ Ref> +useNuxtData():‌ Ref> ``` ## Examples From 3669e3bc20e571358dc8ed640d006aca76dfa205 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 5 Dec 2022 13:08:22 +0100 Subject: [PATCH 19/24] refactor: always require key --- .../1.docs/3.api/1.composables/use-nuxt-data.md | 1 - packages/nuxt/src/app/composables/asyncData.ts | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index ffb9bb9d7b3..9b5659b3637 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -6,7 +6,6 @@ ```ts useNuxtData (key: string): Ref -useNuxtData():‌ Ref> ``` ## Examples diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index efde465b79f..1ab8a114d59 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -268,17 +268,15 @@ export function useLazyAsyncData< return useAsyncData(key, handler, { ...options, lazy: true }, null) } -export function useNuxtData (key: string): Ref -export function useNuxtData (): Ref> -export function useNuxtData (key?: string): unknown { +export function useNuxtData (key: string): Ref { const nuxt = useNuxtApp() - // initialize value when key is not already set - if (key && nuxt.payload.data[key] === undefined) { + // Initialize value when key is not already set + if (nuxt.payload.data[key] === undefined) { nuxt.payload.data[key] = null } - return key ? toRef(nuxt.payload.data, key) : ref(nuxt.payload.data) + return toRef(nuxt.payload.data, key) } export async function refreshNuxtData (keys?: string | string[]): Promise { From 73a2dd06b8be23d31f2cc0d811ce5259e449bba0 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 5 Dec 2022 13:11:35 +0100 Subject: [PATCH 20/24] update docs --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 9b5659b3637..d0ab0038472 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -1,6 +1,6 @@ # `useNuxtData` -`useNuxtData` gives you access to the cache of `useAsyncData`, `useLazyAsyncData`, `useFetch` and `useLazyFetch`. +`useNuxtData` gives you access to the current value of `useAsyncData`, `useLazyAsyncData`, `useFetch` and `useLazyFetch` with explicitly provided key. ## Type From 1752c879d7569f882b2bc7688a6a09e88cd6b2a8 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 5 Dec 2022 13:19:04 +0100 Subject: [PATCH 21/24] refactor: namespace data --- .../1.docs/3.api/1.composables/use-nuxt-data.md | 10 +++++----- packages/nuxt/src/app/composables/asyncData.ts | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index d0ab0038472..1cbe7f42a28 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -5,7 +5,7 @@ ## Type ```ts -useNuxtData (key: string): Ref +useNuxtData (key: string): { data: Ref } ``` ## Examples @@ -27,7 +27,7 @@ const { data } = await useFetch(`/api/posts/${postId}`, { key: `post-${postId}`, default: () => { // Find the individual post from the cache and set it as the default value. - return useNuxtData('posts').value.find(post => post.id === postId) + return useNuxtData('posts').data.value.find(post => post.id === postId) } }) ``` @@ -55,12 +55,12 @@ const { data } = await useFetch('/api/addTodo', { todo: newTodo.value }, onRequest () { - previousTodos.value = useNuxtData('todos').value // Store the previously cached value to restore if fetch fails. + previousTodos.value = useNuxtData('todos').data.value // Store the previously cached value to restore if fetch fails. - useNuxtData('todos').value.push(newTodo.value) // Optimistically update the todos. + useNuxtData('todos').data.value.push(newTodo.value) // Optimistically update the todos. }, onRequestError () { - useNuxtData('todos').value = previousTodos.value // Rollback the data if the request failed. + useNuxtData('todos').data.value = previousTodos.value // Rollback the data if the request failed. }, async onResponse () { await refreshNuxtData('todos') // Invalidate todos in the background if the request succeeded. diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 1ab8a114d59..cfa0216cc5c 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -268,7 +268,7 @@ export function useLazyAsyncData< return useAsyncData(key, handler, { ...options, lazy: true }, null) } -export function useNuxtData (key: string): Ref { +export function useNuxtData (key: string): { data: Ref } { const nuxt = useNuxtApp() // Initialize value when key is not already set @@ -276,7 +276,9 @@ export function useNuxtData (key: string): Ref { nuxt.payload.data[key] = null } - return toRef(nuxt.payload.data, key) + return { + data: toRef(nuxt.payload.data, key) + } } export async function refreshNuxtData (keys?: string | string[]): Promise { From ed10d745ef1682007e05ffa0d0639564f3f2098b Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 5 Dec 2022 13:21:06 +0100 Subject: [PATCH 22/24] update and simplify second example --- docs/content/1.docs/3.api/1.composables/use-nuxt-data.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index 1cbe7f42a28..e21614270cb 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -48,6 +48,7 @@ const { data } = await useFetch('/api/todos', { const newTodo = ref('') const previousTodos = ref([]) +const { data: todos } = useNuxtData('todos') const { data } = await useFetch('/api/addTodo', { key: 'addTodo', method: 'post', @@ -55,12 +56,12 @@ const { data } = await useFetch('/api/addTodo', { todo: newTodo.value }, onRequest () { - previousTodos.value = useNuxtData('todos').data.value // Store the previously cached value to restore if fetch fails. + previousTodos.value = todos.value // Store the previously cached value to restore if fetch fails. - useNuxtData('todos').data.value.push(newTodo.value) // Optimistically update the todos. + todos.value.push(newTodo.value) // Optimistically update the todos. }, onRequestError () { - useNuxtData('todos').data.value = previousTodos.value // Rollback the data if the request failed. + todos.value = previousTodos.value // Rollback the data if the request failed. }, async onResponse () { await refreshNuxtData('todos') // Invalidate todos in the background if the request succeeded. From 0fe863898d8debf87a9decaf33a825956bd93659 Mon Sep 17 00:00:00 2001 From: pooya parsa Date: Mon, 5 Dec 2022 13:54:35 +0100 Subject: [PATCH 23/24] Update packages/nuxt/src/app/composables/asyncData.ts Co-authored-by: Daniel Roe --- packages/nuxt/src/app/composables/asyncData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index cfa0216cc5c..8543877409e 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -272,7 +272,7 @@ export function useNuxtData (key: string): { data: Ref Date: Mon, 5 Dec 2022 14:03:15 +0100 Subject: [PATCH 24/24] update docs --- .../3.api/1.composables/use-nuxt-data.md | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md index e21614270cb..898042695e2 100644 --- a/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md +++ b/docs/content/1.docs/3.api/1.composables/use-nuxt-data.md @@ -1,6 +1,10 @@ # `useNuxtData` -`useNuxtData` gives you access to the current value of `useAsyncData`, `useLazyAsyncData`, `useFetch` and `useLazyFetch` with explicitly provided key. +`useNuxtData` gives you access to the current cached value of `useAsyncData`, `useLazyAsyncData`, `useFetch` and `useLazyFetch` with explicitly provided key. + +::Alert +This feature is not released yet. You can beta test using [Edge Channel](https://nuxt.com/docs/guide/going-further/edge-channel). +:: ## Type @@ -14,20 +18,20 @@ useNuxtData (key: string): { data: Ref } The example below shows how you can use cached data as a placeholder while the most recent data is being fetched from the server. -```ts -// In Archive.vue -const { data } = await useFetch('/api/posts', { - key: 'posts', // You need to set a key to access the data later. -}) +```ts [archive.vue] +// We can access same data later using 'posts' key +const { data } = await useFetch('/api/posts', { key: 'posts' }) ``` -```ts -// In Single.vue +```ts [single.vue] +// Access to the cached value of useFetch in archive.vue +const { data: posts } = useNuxtData('posts') + const { data } = await useFetch(`/api/posts/${postId}`, { key: `post-${postId}`, default: () => { // Find the individual post from the cache and set it as the default value. - return useNuxtData('posts').data.value.find(post => post.id === postId) + return posts.value.find(post => post.id === postId) } }) ``` @@ -36,19 +40,18 @@ const { data } = await useFetch(`/api/posts/${postId}`, { We can leverage the cache to update the UI after a mutation, while the data is being invalidated in the background. -```ts -// In Todos.vue -const { data } = await useFetch('/api/todos', { - key: 'todos' -}) +```ts [todos.vue] +// We can access same data later using 'todos' key +const { data } = await useFetch('/api/todos', { key: 'todos' }) ``` -```ts -// In AddTodo.vue +```ts [add-todo.vue] const newTodo = ref('') const previousTodos = ref([]) +// Access to the cached value of useFetch in todos.vue const { data: todos } = useNuxtData('todos') + const { data } = await useFetch('/api/addTodo', { key: 'addTodo', method: 'post',