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 @@
+
+
+
+
+
+ Open bar
+
+
+ Open foo
+
+
+
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 @@
+
+
+
+
+