mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +00:00
feat(nuxt): tryUseNuxtApp
composable (#25031)
This commit is contained in:
parent
2bfe01d26f
commit
6b651cf7bf
@ -28,6 +28,8 @@ You can think of it as **Runtime Core**.
|
||||
This context can be accessed using [`useNuxtApp()`](/docs/api/composables/use-nuxt-app) composable within Nuxt plugins and `<script setup>` and vue composables.
|
||||
Global usage is possible for the browser but not on the server, to avoid sharing context between users.
|
||||
|
||||
Since [`useNuxtApp`](/docs/api/composables/use-nuxt-app) throws an exception if context is currently unavailable, if your composable does not always require `nuxtApp`, you can use [`tryUseNuxtApp`](/docs/api/composables/use-nuxt-app#tryusenuxtapp) instead, which will return `null` instead of throwing an exception.
|
||||
|
||||
To extend the `nuxtApp` interface and hook into different stages or access contexts, we can use [Nuxt Plugins](/docs/guide/directory-structure/plugins).
|
||||
|
||||
Check [Nuxt App](/docs/api/composables/use-nuxt-app) for more information about this interface.
|
||||
|
@ -30,6 +30,8 @@ export function useMyComposable () {
|
||||
}
|
||||
```
|
||||
|
||||
If your composable does not always need `nuxtApp` or you simply want to check if it is present or not, since [`useNuxtApp`](/docs/api/composables/use-nuxt-app) throws an exception, you can use [`tryUseNuxtApp`](/docs/api/composables/use-nuxt-app#tryusenuxtapp) instead.
|
||||
|
||||
Plugins also receive `nuxtApp` as the first argument for convenience.
|
||||
|
||||
:read-more{to="/docs/guide/directory-structure/plugins"}
|
||||
|
@ -16,6 +16,8 @@ const nuxtApp = useNuxtApp()
|
||||
</script>
|
||||
```
|
||||
|
||||
If runtime context is unavailable in your scope, `useNuxtApp` will throw an exception when called. You can use [`tryUseNuxtApp`](#tryusenuxtapp) instead for composables that do not require `nuxtApp`, or to simply check if context is available or not without an exception.
|
||||
|
||||
## Methods
|
||||
|
||||
### `provide (name, value)`
|
||||
@ -257,3 +259,22 @@ Native async context support works currently in Bun and Node.
|
||||
::
|
||||
|
||||
:read-more{to="/docs/guide/going-further/experimental-features#asynccontext"}
|
||||
|
||||
## tryUseNuxtApp
|
||||
|
||||
This function works exactly the same as `useNuxtApp`, but returns `null` if context is unavailable instead of throwing an exception.
|
||||
|
||||
You can use it for composables that do not require `nuxtApp`, or to simply check if context is available or not without an exception.
|
||||
|
||||
Example usage:
|
||||
|
||||
```ts [composable.ts]
|
||||
export function useStandType() {
|
||||
// Always works on the client
|
||||
if (tryUseNuxtApp()) {
|
||||
return useRuntimeConfig().public.STAND_TYPE
|
||||
} else {
|
||||
return process.env.STAND_TYPE
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -439,8 +439,10 @@ export function callWithNuxt<T extends (...args: any[]) => any> (nuxt: NuxtApp |
|
||||
/*@__NO_SIDE_EFFECTS__*/
|
||||
/**
|
||||
* Returns the current Nuxt instance.
|
||||
*
|
||||
* Returns `null` if Nuxt instance is unavailable.
|
||||
*/
|
||||
export function useNuxtApp (): NuxtApp {
|
||||
export function tryUseNuxtApp (): NuxtApp | null {
|
||||
let nuxtAppInstance
|
||||
if (hasInjectionContext()) {
|
||||
nuxtAppInstance = getCurrentInstance()?.appContext.app.$nuxt
|
||||
@ -448,6 +450,18 @@ export function useNuxtApp (): NuxtApp {
|
||||
|
||||
nuxtAppInstance = nuxtAppInstance || nuxtAppCtx.tryUse()
|
||||
|
||||
return nuxtAppInstance || null
|
||||
}
|
||||
|
||||
/*@__NO_SIDE_EFFECTS__*/
|
||||
/**
|
||||
* Returns the current Nuxt instance.
|
||||
*
|
||||
* Throws an error if Nuxt instance is unavailable.
|
||||
*/
|
||||
export function useNuxtApp (): NuxtApp {
|
||||
const nuxtAppInstance = tryUseNuxtApp()
|
||||
|
||||
if (!nuxtAppInstance) {
|
||||
if (import.meta.dev) {
|
||||
throw new Error('[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables`.')
|
||||
|
@ -18,7 +18,7 @@ const granularAppPresets: InlinePreset[] = [
|
||||
imports: ['defineNuxtLink']
|
||||
},
|
||||
{
|
||||
imports: ['useNuxtApp', 'defineNuxtPlugin', 'definePayloadPlugin', 'useRuntimeConfig', 'defineAppConfig'],
|
||||
imports: ['useNuxtApp', 'tryUseNuxtApp', 'defineNuxtPlugin', 'definePayloadPlugin', 'useRuntimeConfig', 'defineAppConfig'],
|
||||
from: '#app/nuxt'
|
||||
},
|
||||
{
|
||||
|
@ -2130,6 +2130,12 @@ describe.skipIf(process.env.TEST_CONTEXT !== 'async')('Async context', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe.skipIf(process.env.TEST_CONTEXT === 'async')('Async context', () => {
|
||||
it('should be unavailable', async () => {
|
||||
expect(await $fetch('/async-context')).toContain('"hasApp": false')
|
||||
})
|
||||
})
|
||||
|
||||
describe.skipIf(isWindows)('useAsyncData', () => {
|
||||
it('works after useNuxtData call', async () => {
|
||||
const page = await createPage('/useAsyncData/nuxt-data')
|
||||
|
@ -12,7 +12,7 @@ async function fn1 () {
|
||||
|
||||
async function fn2 () {
|
||||
await delay()
|
||||
const app = useNuxtApp()
|
||||
const app = tryUseNuxtApp()
|
||||
return {
|
||||
hasApp: !!app
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user