useNuxtApp
Accede al contexto de ejecución compartido de la aplicación Nuxt.
useNuxtApp
es un composable incorporado que proporciona una forma de acceder al contexto de ejecución compartido de Nuxt, también conocido como el contexto de Nuxt, que está disponible tanto en el lado del cliente como en el del servidor (pero no dentro de las rutas de Nitro). Te ayuda a acceder a la instancia de la aplicación Vue, hooks de ejecución, variables de configuración de ejecución y estados internos, como ssrContext
y payload
.
const nuxtApp = useNuxtApp()
Si el contexto de ejecución no está disponible en tu ámbito, useNuxtApp
lanzará una excepción cuando se llame. Puedes usar tryUseNuxtApp
en su lugar para composables que no requieren nuxtApp
, o simplemente para verificar si el contexto está disponible o no sin una excepción.
Métodos
provide (name, value)
nuxtApp
es un contexto de ejecución que puedes extender usando plugins de Nuxt. Usa la función provide
para crear plugins de Nuxt que hagan valores y métodos auxiliares disponibles en tu aplicación Nuxt a través de todos los composables y componentes.
La función provide
acepta los parámetros name
y value
.
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)
// Imprime "Hello name!"
console.log(nuxtApp.$hello('name'))
Como puedes ver en el ejemplo anterior, $hello
se ha convertido en la nueva y personalizada parte del contexto nuxtApp
y está disponible en todos los lugares donde nuxtApp
es accesible.
hook(name, cb)
Los hooks disponibles en nuxtApp
te permiten personalizar los aspectos de ejecución de tu aplicación Nuxt. Puedes usar hooks de ejecución en composables de Vue.js y plugins de Nuxt para engancharte en el ciclo de vida de renderizado.
La función hook
es útil para agregar lógica personalizada al engancharse en el ciclo de vida de renderizado en un punto específico. La función hook
se usa principalmente al crear plugins de Nuxt.
Consulta Hooks de Ejecución para ver los hooks de ejecución disponibles llamados por Nuxt.
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:start', () => {
/* tu código va aquí */
})
nuxtApp.hook('vue:error', (..._args) => {
console.log('vue:error')
// if (import.meta.client) {
// console.log(..._args)
// }
})
})
callHook(name, ...args)
callHook
devuelve una promesa cuando se llama con cualquiera de los hooks existentes.
await nuxtApp.callHook('my-plugin:init')
Propiedades
useNuxtApp()
expone las siguientes propiedades que puedes usar para extender y personalizar tu aplicación y compartir estado, datos y variables.
vueApp
vueApp
es la instancia de aplicación global de Vue.js a la que puedes acceder a través de nuxtApp
.
Algunos métodos útiles:
component()
- Registra un componente global si se pasa tanto un nombre como una definición de componente, o recupera uno ya registrado si solo se pasa el nombre.directive()
- Registra una directiva personalizada global si se pasa tanto un nombre como una definición de directiva, o recupera una ya registrada si solo se pasa el nombre (ejemplo).use()
- Instala un Plugin de Vue.js (ejemplo).
ssrContext
ssrContext
se genera durante el renderizado del lado del servidor y solo está disponible en el lado del servidor.
Nuxt expone las siguientes propiedades a través de ssrContext
:
url
(string) - URL de la solicitud actual.event
(evento de solicitud h3js/h3) - Accede a la solicitud y respuesta de la ruta actual.payload
(objeto) - Objeto de carga útil de NuxtApp.
payload
payload
expone datos y variables de estado del lado del servidor al lado del cliente. Las siguientes claves estarán disponibles en el cliente después de haber sido pasadas desde el lado del servidor:
-
serverRendered
(boolean) - Indica si la respuesta está renderizada del lado del servidor. -
data
(objeto) - Cuando obtienes los datos de un endpoint de API usandouseFetch
ouseAsyncData
, la carga útil resultante puede ser accedida desdepayload.data
. Estos datos se almacenan en caché y te ayudan a evitar obtener los mismos datos en caso de que se realice una solicitud idéntica más de una vez.const { data } = await useAsyncData('count', () => $fetch('/api/count'))
Después de obtener el valor de
count
usandouseAsyncData
en el ejemplo anterior, si accedes apayload.data
, verás{ count: 1 }
registrado allí.Al acceder al mismo
payload.data
desdessrcontext
, puedes acceder al mismo valor también en el lado del servidor. -
state
(objeto) - Cuando usas el composableuseState
en Nuxt para establecer un estado compartido, estos datos de estado se acceden a través depayload.state.[nombre-de-tu-estado]
.plugins/my-plugin.tsexport const useColor = () => useState<string>('color', () => 'pink') export default defineNuxtPlugin((nuxtApp) => { if (import.meta.server) { const color = useColor() } })
También es posible usar tipos más avanzados, como
ref
,reactive
,shallowRef
,shallowReactive
yNuxtError
.Desde Nuxt v3.4, es posible definir tu propio reducer/reviver para tipos que no son soportados por Nuxt.
En el ejemplo a continuación, definimos un reducer (o un serializador) y un reviver (o deserializador) para la clase DateTime de Luxon, usando un plugin de carga útil.
plugins/date-time-payload.ts/** * Este tipo de plugin se ejecuta muy temprano en el ciclo de vida de Nuxt, antes de que revivamos la carga útil. * No tendrás acceso al enrutador u otras propiedades inyectadas por Nuxt. * * Ten en cuenta que la cadena "DateTime" es el identificador de tipo y debe * ser la misma tanto en el reducer como en el reviver. */ export default definePayloadPlugin((nuxtApp) => { definePayloadReducer('DateTime', (value) => { return value instanceof DateTime && value.toJSON() }) definePayloadReviver('DateTime', (value) => { return DateTime.fromISO(value) }) })
isHydrating
Usa nuxtApp.isHydrating
(boolean) para verificar si la aplicación Nuxt se está hidratando en el lado del cliente.
export default defineComponent({
setup (_props, { slots, emit }) {
const nuxtApp = useNuxtApp()
onErrorCaptured((err) => {
if (import.meta.client && !nuxtApp.isHydrating) {
// ...
}
})
}
})
runWithContext
Probablemente estés aquí porque recibiste un mensaje de "Instancia de Nuxt no disponible". Por favor, usa este método con moderación y reporta ejemplos que estén causando problemas, para que finalmente pueda resolverse a nivel del framework.
El método runWithContext
está destinado a ser usado para llamar a una función y darle un contexto de Nuxt explícito. Normalmente, el contexto de Nuxt se pasa implícitamente y no necesitas preocuparte por esto. Sin embargo, al trabajar con escenarios complejos de async
/await
en middleware/plugins, puedes encontrarte con instancias donde la instancia actual ha sido desestablecida después de una llamada asíncrona.
export default defineNuxtRouteMiddleware(async (to, from) => {
const nuxtApp = useNuxtApp()
let user
try {
user = await fetchUser()
// el compilador de Vue/Nuxt pierde el contexto aquí debido al bloque try/catch.
} catch (e) {
user = null
}
if (!user) {
// aplica el contexto de Nuxt correcto a nuestra llamada `navigateTo`.
return nuxtApp.runWithContext(() => navigateTo('/auth'))
}
})
Uso
const result = nuxtApp.runWithContext(() => functionWithContext())
functionWithContext
: Cualquier función que requiera el contexto de la aplicación Nuxt actual. Este contexto se aplicará correctamente de forma automática.
runWithContext
devolverá lo que sea que devuelva functionWithContext
.
Una Explicación Más Profunda del Contexto
La API de Composición de Vue.js (y los composables de Nuxt de manera similar) funcionan dependiendo de un contexto implícito. Durante el ciclo de vida, Vue establece la instancia temporal del componente actual (y Nuxt la instancia temporal de nuxtApp) en una variable global y la desestablece en el mismo tick. Al renderizar en el lado del servidor, hay múltiples solicitudes de diferentes usuarios y nuxtApp ejecutándose en un mismo contexto global. Debido a esto, Nuxt y Vue desestablecen inmediatamente esta instancia global para evitar filtrar una referencia compartida entre dos usuarios o componentes.
¿Qué significa esto? La API de Composición y los Composables de Nuxt solo están disponibles durante el ciclo de vida y en el mismo tick antes de cualquier operación asíncrona:
// --- Interno de Vue ---
const _vueInstance = null
const getCurrentInstance = () => _vueInstance
// ---
// Vue / Nuxt establece una variable global que hace referencia al componente actual en _vueInstance al llamar a setup()
async function setup() {
getCurrentInstance() // Funciona
await someAsyncOperation() // Vue desestablece el contexto en el mismo tick antes de la operación asíncrona!
getCurrentInstance() // null
}
La solución clásica para esto es almacenar en caché la instancia actual en la primera llamada a una variable local como const instance = getCurrentInstance()
y usarla en la siguiente llamada composable, pero el problema es que cualquier llamada composable anidada ahora necesita aceptar explícitamente la instancia como un argumento y no depender del contexto implícito de la API de composición. Esta es una limitación de diseño con los composables y no un problema en sí.
Para superar esta limitación, Vue hace algunos trabajos detrás de escena al compilar nuestro código de aplicación y restaura el contexto después de cada llamada para <script setup>
:
const __instance = getCurrentInstance() // Generado por el compilador de Vue
getCurrentInstance() // ¡Funciona!
await someAsyncOperation() // Vue desestablece el contexto
__restoreInstance(__instance) // Generado por el compilador de Vue
getCurrentInstance() // ¡Todavía funciona!
Para una mejor descripción de lo que Vue realmente hace, consulta unjs/unctx#2 (comentario).
Solución
Aquí es donde runWithContext
puede ser usado para restaurar el contexto, de manera similar a cómo funciona <script setup>
.
Nuxt usa internamente unjs/unctx para soportar composables de manera similar a Vue para plugins y middleware. Esto permite que composables como navigateTo()
funcionen sin pasar directamente nuxtApp
a ellos, brindando los beneficios de DX y rendimiento de la API de Composición a todo el framework de Nuxt.
Los composables de Nuxt tienen el mismo diseño que la API de Composición de Vue y, por lo tanto, necesitan una solución similar para hacer mágicamente esta transformación. Consulta unjs/unctx#2 (propuesta), unjs/unctx#4 (implementación de la transformación), y nuxt/framework#3884 (Integración en Nuxt).
Actualmente, Vue solo soporta la restauración de contexto asíncrono para <script setup>
para el uso de async/await. En Nuxt, se agregó soporte de transformación para defineNuxtPlugin()
y defineNuxtRouteMiddleware()
, lo que significa que cuando los usas, Nuxt los transforma automáticamente con restauración de contexto.
Problemas Restantes
La transformación unjs/unctx
para restaurar automáticamente el contexto parece tener errores con declaraciones try/catch
que contienen await
, lo que finalmente necesita ser resuelto para eliminar el requisito de la solución alternativa sugerida anteriormente.
Contexto Asíncrono Nativo
Usando una nueva característica experimental, es posible habilitar el soporte de contexto asíncrono nativo usando Node.js AsyncLocalStorage
y el nuevo soporte de unctx para hacer que el contexto asíncrono esté disponible nativamente para cualquier composable asíncrono anidado sin necesidad de una transformación o paso/llamada manual con contexto.
El soporte de contexto asíncrono nativo funciona actualmente en Bun y Node.
tryUseNuxtApp
Esta función funciona exactamente igual que useNuxtApp
, pero devuelve null
si el contexto no está disponible en lugar de lanzar una excepción.
Puedes usarlo para composables que no requieren nuxtApp
, o simplemente para verificar si el contexto está disponible o no sin una excepción.
Ejemplo de uso:
export function useStandType() {
// Siempre funciona en el cliente
if (tryUseNuxtApp()) {
return useRuntimeConfig().public.STAND_TYPE
} else {
return process.env.STAND_TYPE
}
}
※Esta página es una traducción no oficial de la documentación oficial de Nuxt.js.
La página correspondiente en la documentación oficial está aquí:
https://nuxt.com/docs/3.x/api/composables/use-nuxt-app