mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-22 08:29:46 +00:00
fix(nuxt): ensure provide
/ inject
work in setup
of defineNuxtComponent
(#30982)
This commit is contained in:
parent
6d9ddff209
commit
b65dfbc98e
@ -2,7 +2,7 @@ import { getCurrentInstance, reactive, toRefs } from 'vue'
|
||||
import type { DefineComponent, defineComponent } from 'vue'
|
||||
import { useHead } from '@unhead/vue'
|
||||
import type { NuxtApp } from '../nuxt'
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import { getNuxtAppCtx, useNuxtApp } from '../nuxt'
|
||||
import { useAsyncData } from './asyncData'
|
||||
import { useRoute } from './router'
|
||||
import { createError } from './error'
|
||||
@ -32,7 +32,7 @@ async function runLegacyAsyncData (res: Record<string, any> | Promise<Record<str
|
||||
export const defineNuxtComponent: typeof defineComponent =
|
||||
function defineNuxtComponent (...args: any[]): any {
|
||||
const [options, key] = args
|
||||
const { setup } = options
|
||||
const { setup } = options as DefineComponent
|
||||
|
||||
// Avoid wrapping if no options api is used
|
||||
if (!setup && !options.asyncData && !options.head) {
|
||||
@ -48,7 +48,18 @@ export const defineNuxtComponent: typeof defineComponent =
|
||||
...options,
|
||||
setup (props, ctx) {
|
||||
const nuxtApp = useNuxtApp()
|
||||
const res = setup ? Promise.resolve(nuxtApp.runWithContext(() => setup(props, ctx))).then(r => r || {}) : {}
|
||||
|
||||
let res = {}
|
||||
if (setup) {
|
||||
const fn = (): Promise<Record<string, any>> => Promise.resolve(setup(props, ctx)).then((r: any) => r || {})
|
||||
const nuxtAppCtx = getNuxtAppCtx(nuxtApp._id)
|
||||
if (import.meta.server) {
|
||||
res = nuxtAppCtx.callAsync(nuxtApp, fn)
|
||||
} else {
|
||||
nuxtAppCtx.set(nuxtApp)
|
||||
res = fn()
|
||||
}
|
||||
}
|
||||
|
||||
const promises: Promise<any>[] = []
|
||||
if (options.asyncData) {
|
||||
|
@ -24,7 +24,7 @@ import type { RouteAnnouncer } from '../app/composables/route-announcer'
|
||||
// @ts-expect-error virtual file
|
||||
import { appId, chunkErrorEvent, multiApp } from '#build/nuxt.config.mjs'
|
||||
|
||||
function getNuxtAppCtx (id = appId || 'nuxt-app') {
|
||||
export function getNuxtAppCtx (id = appId || 'nuxt-app') {
|
||||
return getContext<NuxtApp>(id, {
|
||||
asyncContext: !!__NUXT_ASYNC_CONTEXT__ && import.meta.server,
|
||||
})
|
||||
|
@ -2862,14 +2862,28 @@ describe('lazy import components', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('defineNuxtComponent watch duplicate', () => {
|
||||
it('test after navigation duplicate', async () => {
|
||||
describe('defineNuxtComponent', () => {
|
||||
it('watches duplicate updates after navigation', 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')
|
||||
})
|
||||
|
||||
it('get correctly route when navigating between routes', async () => {
|
||||
const { page } = await renderPage('/define-nuxt-component/route-1')
|
||||
await page.getByText('Go to route 2').click()
|
||||
expect(await page.getByTestId('define-nuxt-component-route-2-path').innerText()).include('route-2')
|
||||
|
||||
await page.getByText('Go to route 1').click()
|
||||
expect(await page.getByTestId('define-nuxt-component-route-1-path').innerText()).include('route-1')
|
||||
})
|
||||
|
||||
it ('should get correctly inject value', async () => {
|
||||
const { page } = await renderPage('/define-nuxt-component/inject')
|
||||
expect(await page.getByTestId('define-nuxt-component-inject-value').innerText()).include('bar')
|
||||
})
|
||||
})
|
||||
|
||||
describe('namespace access to useNuxtApp', () => {
|
||||
|
7
test/fixtures/basic/pages/define-nuxt-component/inject.vue
vendored
Normal file
7
test/fixtures/basic/pages/define-nuxt-component/inject.vue
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
provide('foo', 'bar')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtPage />
|
||||
</template>
|
17
test/fixtures/basic/pages/define-nuxt-component/inject/index.vue
vendored
Normal file
17
test/fixtures/basic/pages/define-nuxt-component/inject/index.vue
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
export default defineNuxtComponent({
|
||||
name: 'DefineNuxtComponentTest',
|
||||
setup () {
|
||||
const value = inject('foo')
|
||||
return {
|
||||
value,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div data-testid="define-nuxt-component-inject-value">
|
||||
{{ value }}
|
||||
</div>
|
||||
</template>
|
23
test/fixtures/basic/pages/define-nuxt-component/route-1.vue
vendored
Normal file
23
test/fixtures/basic/pages/define-nuxt-component/route-1.vue
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
export default defineNuxtComponent({
|
||||
name: 'DefineNuxtComponentTest',
|
||||
setup () {
|
||||
const route = useRoute()
|
||||
const path = route.path.toString()
|
||||
|
||||
return {
|
||||
path,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>route-1</h1>
|
||||
<NuxtLink to="/define-nuxt-component/route-2">Go to route 2</NuxtLink>
|
||||
<div data-testid="define-nuxt-component-route-1-path">
|
||||
{{ path }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
23
test/fixtures/basic/pages/define-nuxt-component/route-2.vue
vendored
Normal file
23
test/fixtures/basic/pages/define-nuxt-component/route-2.vue
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
export default defineNuxtComponent({
|
||||
name: 'DefineNuxtComponentTest',
|
||||
setup () {
|
||||
const route = useRoute()
|
||||
const path = route.path.toString()
|
||||
|
||||
return {
|
||||
path,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>route-2</h2>
|
||||
<NuxtLink to="/define-nuxt-component/route-1">Go to route 1</NuxtLink>
|
||||
<div data-testid="define-nuxt-component-route-2-path">
|
||||
{{ path }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
Loading…
Reference in New Issue
Block a user