From ea21feaaf437f689fc98d05382bffedc1d03afa2 Mon Sep 17 00:00:00 2001 From: Danila Rodichkin Date: Fri, 3 May 2024 13:27:38 +0300 Subject: [PATCH] fix(nuxt): don't overwrite existing scope in `runWithContext` (#26976) --- .../nuxt/src/app/composables/asyncData.ts | 8 ++--- packages/nuxt/src/app/nuxt.ts | 4 +-- test/basic.test.ts | 10 ++++++ .../pages/define-nuxt-component/index.vue | 29 ++++++++++++++++ .../define-nuxt-component/nested/[foo].vue | 34 +++++++++++++++++++ 5 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/basic/pages/define-nuxt-component/index.vue create mode 100644 test/fixtures/basic/pages/define-nuxt-component/nested/[foo].vue diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 5426155be3..5e9f9bf081 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -378,9 +378,7 @@ export function useAsyncData< const hasScope = getCurrentScope() if (options.watch) { const unsub = watch(options.watch, () => asyncData.refresh()) - if (instance) { - onUnmounted(unsub) - } else if (hasScope) { + if (hasScope) { onScopeDispose(unsub) } } @@ -389,9 +387,7 @@ export function useAsyncData< await asyncData.refresh() } }) - if (instance) { - onUnmounted(off) - } else if (hasScope) { + if (hasScope) { onScopeDispose(off) } } diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index a89224deca..ee602fa58b 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -1,4 +1,4 @@ -import { effectScope, getCurrentInstance, hasInjectionContext, reactive } from 'vue' +import { effectScope, getCurrentInstance, getCurrentScope, hasInjectionContext, reactive } from 'vue' import type { App, EffectScope, Ref, VNode, onErrorCaptured } from 'vue' import type { RouteLocationNormalizedLoaded } from '#vue-router' import type { HookCallback, Hookable } from 'hookable' @@ -255,7 +255,7 @@ export function createNuxtApp (options: CreateOptions) { data: {}, }, runWithContext (fn: any) { - if (nuxtApp._scope.active) { + if (nuxtApp._scope.active && !getCurrentScope()) { return nuxtApp._scope.run(() => callWithNuxt(nuxtApp, fn)) } return callWithNuxt(nuxtApp, fn) diff --git a/test/basic.test.ts b/test/basic.test.ts index 975ffd3a80..5e0306c9fc 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -2605,3 +2605,13 @@ describe('lazy import components', () => { expect(html).toContain('lazy-named-comp-server') }) }) + +describe('defineNuxtComponent watch duplicate', () => { + it('test after navigation duplicate', async () => { + const { page } = await renderPage('/define-nuxt-component') + await page.getByTestId('define-nuxt-component-bar').click() + await page.getByTestId('define-nuxt-component-state').click() + await page.getByTestId('define-nuxt-component-foo').click() + expect(await page.getByTestId('define-nuxt-component-state').first().innerText()).toBe('2') + }) +}) diff --git a/test/fixtures/basic/pages/define-nuxt-component/index.vue b/test/fixtures/basic/pages/define-nuxt-component/index.vue new file mode 100644 index 0000000000..cdbaac8d45 --- /dev/null +++ b/test/fixtures/basic/pages/define-nuxt-component/index.vue @@ -0,0 +1,29 @@ + + + diff --git a/test/fixtures/basic/pages/define-nuxt-component/nested/[foo].vue b/test/fixtures/basic/pages/define-nuxt-component/nested/[foo].vue new file mode 100644 index 0000000000..0081c2e470 --- /dev/null +++ b/test/fixtures/basic/pages/define-nuxt-component/nested/[foo].vue @@ -0,0 +1,34 @@ + + +