fix(nuxt): key distinct pages differently for legacy asyncData (#21263)

This commit is contained in:
Daniel Roe 2023-06-05 19:36:26 +01:00 committed by GitHub
parent 8453feedcb
commit ec72066f91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 5 deletions

View File

@ -13,8 +13,9 @@ async function runLegacyAsyncData (res: Record<string, any> | Promise<Record<str
const nuxtApp = useNuxtApp()
const route = useRoute()
const vm = getCurrentInstance()!
const { fetchKey } = vm.proxy!.$options
const key = typeof fetchKey === 'function' ? fetchKey(() => '') : fetchKey || route.fullPath
const { fetchKey, _fetchKeyBase } = vm.proxy!.$options
const key = (typeof fetchKey === 'function' ? fetchKey(() => '') : fetchKey) ||
([_fetchKeyBase, route.fullPath, route.matched.findIndex(r => Object.values(r.components || {}).includes(vm.type))].join(':'))
const { data, error } = await useAsyncData(`options:asyncdata:${key}`, () => nuxtApp.runWithContext(() => fn(nuxtApp)))
if (error.value) {
throw createError(error.value)
@ -27,7 +28,8 @@ async function runLegacyAsyncData (res: Record<string, any> | Promise<Record<str
}
export const defineNuxtComponent: typeof defineComponent =
function defineNuxtComponent (options: any): any {
function defineNuxtComponent (...args: any[]): any {
const [options, key] = args
const { setup } = options
// Avoid wrapping if no options api is used
@ -40,6 +42,7 @@ export const defineNuxtComponent: typeof defineComponent =
return {
[NuxtComponentIndicator]: true,
_fetchKeyBase: key,
...options,
setup (props, ctx) {
const nuxtApp = useNuxtApp()

View File

@ -146,6 +146,7 @@ export default defineUntypedSchema({
*/
keyedComposables: {
$resolve: (val) => [
{ name: 'defineNuxtComponent', argumentLength: 2 },
{ name: 'useState', argumentLength: 2 },
{ name: 'useFetch', argumentLength: 3 },
{ name: 'useAsyncData', argumentLength: 3 },

View File

@ -578,8 +578,27 @@ describe('legacy async data', () => {
it('should work with defineNuxtComponent', async () => {
const html = await $fetch('/legacy/async-data')
expect(html).toContain('<div>Hello API</div>')
expect(html).toContain('<div>fooChild</div>')
expect(html).toContain('<div>fooParent</div>')
const { script } = parseData(html)
expect(script.data['options:asyncdata:/legacy/async-data'].hello).toEqual('Hello API')
expect(script.data['options:asyncdata:hello'].hello).toBe('Hello API')
expect(Object.values(script.data)).toMatchInlineSnapshot(`
[
{
"baz": "qux",
"foo": "bar",
},
{
"hello": "Hello API",
},
{
"fooParent": "fooParent",
},
{
"fooChild": "fooChild",
},
]
`)
})
})

View File

@ -1,11 +1,13 @@
<template>
<div>
{{ hello }}
<div>{{ hello }}</div>
<NuxtPage />
</div>
</template>
<script>
export default defineNuxtComponent({
fetchKey: () => 'hello',
async setup () {
await nextTick()
useRuntimeConfig()

View File

@ -0,0 +1,16 @@
<template>
<div>
<div>{{ fooParent }}</div>
<NuxtPage />
</div>
</template>
<script>
export default defineNuxtComponent({
asyncData () {
return {
fooParent: 'fooParent'
}
}
})
</script>

View File

@ -0,0 +1,13 @@
<template>
<div>{{ fooChild }}</div>
</template>
<script>
export default defineNuxtComponent({
asyncData () {
return {
fooChild: 'fooChild'
}
}
})
</script>