mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-28 16:42:04 +00:00
fix: pass tests
This commit is contained in:
parent
561f34927e
commit
3366268fb7
@ -138,7 +138,7 @@ export function useAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = null,
|
DefaultT = null,
|
||||||
> (
|
>(
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
||||||
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | null>
|
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | null>
|
||||||
@ -154,7 +154,7 @@ export function useAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = DataT,
|
DefaultT = DataT,
|
||||||
> (
|
>(
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
||||||
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | null>
|
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | null>
|
||||||
@ -171,7 +171,7 @@ export function useAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = null,
|
DefaultT = null,
|
||||||
> (
|
>(
|
||||||
key: string,
|
key: string,
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
||||||
@ -189,7 +189,7 @@ export function useAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = DataT,
|
DefaultT = DataT,
|
||||||
> (
|
>(
|
||||||
key: string,
|
key: string,
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
|
||||||
@ -200,7 +200,7 @@ export function useAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = null,
|
DefaultT = null,
|
||||||
> (...args: any[]): AsyncData<PickFrom<DataT, PickKeys>, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | null> {
|
>(...args: any[]): AsyncData<PickFrom<DataT, PickKeys>, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | null> {
|
||||||
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
||||||
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
||||||
|
|
||||||
@ -274,9 +274,17 @@ export function useAsyncData<
|
|||||||
(nuxtApp._asyncDataPromises[key] as any).cancelled = true
|
(nuxtApp._asyncDataPromises[key] as any).cancelled = true
|
||||||
}
|
}
|
||||||
// Avoid fetching same key that is already fetched
|
// Avoid fetching same key that is already fetched
|
||||||
if (!opts.force && hasCachedData(opts._triggeredBy)) {
|
if(opts._triggeredBy === 'initial' && !opts.force && nuxtApp.isHydrating && hasCachedData(opts._triggeredBy)) {
|
||||||
return Promise.resolve(options.getCachedData!(key, opts._triggeredBy))
|
return Promise.resolve(options.getCachedData!(key, opts._triggeredBy))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If cache changed based on the triggeredBy, set new data result
|
||||||
|
if (!opts.force && hasCachedData(opts._triggeredBy)) {
|
||||||
|
const result = options.getCachedData!(key, opts._triggeredBy)
|
||||||
|
asyncData.data.value = result
|
||||||
|
return Promise.resolve(result)
|
||||||
|
}
|
||||||
|
|
||||||
asyncData.pending.value = true
|
asyncData.pending.value = true
|
||||||
asyncData.status.value = 'pending'
|
asyncData.status.value = 'pending'
|
||||||
// TODO: Cancel previous promise
|
// TODO: Cancel previous promise
|
||||||
@ -325,7 +333,7 @@ export function useAsyncData<
|
|||||||
return nuxtApp._asyncDataPromises[key]!
|
return nuxtApp._asyncDataPromises[key]!
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialFetch = () => asyncData.refresh({ _triggeredBy: 'refresh:manual' })
|
const initialFetch = () => asyncData.refresh({ _triggeredBy: 'initial' })
|
||||||
|
|
||||||
const fetchOnServer = options.server !== false && nuxtApp.payload.serverRendered
|
const fetchOnServer = options.server !== false && nuxtApp.payload.serverRendered
|
||||||
|
|
||||||
@ -372,7 +380,7 @@ export function useAsyncData<
|
|||||||
initialFetch()
|
initialFetch()
|
||||||
}
|
}
|
||||||
if (options.watch) {
|
if (options.watch) {
|
||||||
watch(options.watch, () => asyncData.refresh({ _triggeredBy: 'watch'}))
|
watch(options.watch, () => asyncData.refresh({ _triggeredBy: 'watch' }))
|
||||||
}
|
}
|
||||||
const off = nuxtApp.hook('app:data:refresh', async (keys, force) => {
|
const off = nuxtApp.hook('app:data:refresh', async (keys, force) => {
|
||||||
if (!keys || keys.includes(key)) {
|
if (!keys || keys.includes(key)) {
|
||||||
@ -397,7 +405,7 @@ export function useLazyAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = null,
|
DefaultT = null,
|
||||||
> (
|
>(
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
||||||
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
|
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
|
||||||
@ -407,7 +415,7 @@ export function useLazyAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = DataT,
|
DefaultT = DataT,
|
||||||
> (
|
>(
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
||||||
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
|
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
|
||||||
@ -417,7 +425,7 @@ export function useLazyAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = null,
|
DefaultT = null,
|
||||||
> (
|
>(
|
||||||
key: string,
|
key: string,
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
||||||
@ -428,7 +436,7 @@ export function useLazyAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = DataT,
|
DefaultT = DataT,
|
||||||
> (
|
>(
|
||||||
key: string,
|
key: string,
|
||||||
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
handler: (ctx?: NuxtApp) => Promise<ResT>,
|
||||||
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
|
||||||
@ -440,7 +448,7 @@ export function useLazyAsyncData<
|
|||||||
DataT = ResT,
|
DataT = ResT,
|
||||||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
|
||||||
DefaultT = null,
|
DefaultT = null,
|
||||||
> (...args: any[]): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null> {
|
>(...args: any[]): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null> {
|
||||||
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
const autoKey = typeof args[args.length - 1] === 'string' ? args.pop() : undefined
|
||||||
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
if (typeof args[0] !== 'string') { args.unshift(autoKey) }
|
||||||
const [key, handler, options = {}] = args as [string, (ctx?: NuxtApp) => Promise<ResT>, AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>]
|
const [key, handler, options = {}] = args as [string, (ctx?: NuxtApp) => Promise<ResT>, AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>]
|
||||||
@ -455,7 +463,7 @@ export function useLazyAsyncData<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @since 3.1.0 */
|
/** @since 3.1.0 */
|
||||||
export function useNuxtData<DataT = any> (key: string): { data: Ref<DataT | null> } {
|
export function useNuxtData<DataT = any>(key: string): { data: Ref<DataT | null> } {
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
|
|
||||||
// Initialize value when key is not already set
|
// Initialize value when key is not already set
|
||||||
@ -469,7 +477,7 @@ export function useNuxtData<DataT = any> (key: string): { data: Ref<DataT | null
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @since 3.0.0 */
|
/** @since 3.0.0 */
|
||||||
export async function refreshNuxtData (keys?: string | string[], force?: boolean): Promise<void> {
|
export async function refreshNuxtData(keys?: string | string[], force?: boolean): Promise<void> {
|
||||||
if (import.meta.server) {
|
if (import.meta.server) {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
@ -481,7 +489,7 @@ export async function refreshNuxtData (keys?: string | string[], force?: boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @since 3.0.0 */
|
/** @since 3.0.0 */
|
||||||
export function clearNuxtData (keys?: string | string[] | ((key: string) => boolean)): void {
|
export function clearNuxtData(keys?: string | string[] | ((key: string) => boolean)): void {
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
const _allKeys = Object.keys(nuxtApp.payload.data)
|
const _allKeys = Object.keys(nuxtApp.payload.data)
|
||||||
const _keys: string[] = !keys
|
const _keys: string[] = !keys
|
||||||
@ -509,7 +517,7 @@ export function clearNuxtData (keys?: string | string[] | ((key: string) => bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pick (obj: Record<string, any>, keys: string[]) {
|
function pick(obj: Record<string, any>, keys: string[]) {
|
||||||
const newObj = {}
|
const newObj = {}
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
(newObj as any)[key] = obj[key]
|
(newObj as any)[key] = obj[key]
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
const { data, refresh } = await useAsyncData('key', () => Promise.resolve('something'), {
|
||||||
|
getCachedData: (_, triggeredBy) => {
|
||||||
|
if(triggeredBy === 'refresh:manual') {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Edit this file to play around with Nuxt but never commit changes! -->
|
<!-- Edit this file to play around with Nuxt but never commit changes! -->
|
||||||
<div>
|
<div>
|
||||||
Nuxt 3 Playground
|
{{ data }}
|
||||||
|
<button @click="refresh()" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -239,19 +239,16 @@ describe('useAsyncData', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('will use cache on refresh by default', async () => {
|
it('will use cache on refresh by default', async () => {
|
||||||
let called = 0
|
const { data, refresh } = await useAsyncData(() => 'other value', { getCachedData: () => 'cached' })
|
||||||
const fn = () => called++
|
expect(data.value).toBe('cached')
|
||||||
const { data, refresh } = await useAsyncData(() => 'other value', { getCachedData: () => fn() })
|
|
||||||
expect(data.value).toBe(0)
|
|
||||||
await refresh()
|
await refresh()
|
||||||
expect(data.value).toBe(0)
|
expect(data.value).toBe('cached')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('will not use cache with force option', async () => {
|
it('will not use cache with force option', async () => {
|
||||||
let called = 0
|
let called = 0
|
||||||
const fn = () => called++
|
const fn = () => called++
|
||||||
const { data, refresh } = await useAsyncData(() => 'other value', { getCachedData: () => fn() })
|
const { data, refresh } = await useAsyncData(() => 'other value', { getCachedData: () => fn() })
|
||||||
expect(data.value).toBe(0)
|
|
||||||
await refresh({ force: true })
|
await refresh({ force: true })
|
||||||
expect(data.value).toBe('other value')
|
expect(data.value).toBe('other value')
|
||||||
})
|
})
|
||||||
@ -262,16 +259,18 @@ describe('useAsyncData', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('getCachedData should receive triggeredBy on manual refresh', async () => {
|
it('getCachedData should receive triggeredBy on manual refresh', async () => {
|
||||||
const { data, refresh } = await useAsyncData(() => '', { getCachedData: (_, triggeredBy) => triggeredBy })
|
const { data, refresh } = await useAsyncData(() => '', {
|
||||||
|
getCachedData: (_, triggeredBy) => triggeredBy
|
||||||
|
})
|
||||||
await refresh()
|
await refresh()
|
||||||
expect(data.value).toBe('refresh:manual')
|
expect(data.value).toBe('refresh:manual')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('getCachedData should receive triggeredBy on watch', async () => {
|
it('getCachedData should receive triggeredBy on watch', async () => {
|
||||||
const number = ref(0)
|
const number = ref(0)
|
||||||
const { data } = await useAsyncData(() => '', { getCachedData: (_, triggeredBy) => triggeredBy })
|
const { data } = await useAsyncData(() => '', { getCachedData: (_, triggeredBy) => triggeredBy, watch: [number] })
|
||||||
number.value = 1
|
number.value = 1
|
||||||
// TODO: Maybe setTimeout or similar
|
await new Promise(resolve => setTimeout(resolve, 1))
|
||||||
expect(data.value).toBe('watch')
|
expect(data.value).toBe('watch')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user