useNuxtApp
Acesse o contexto de runtime compartilhado da aplicação Nuxt.
useNuxtApp
é um composable embutido que fornece uma maneira de acessar o contexto de runtime compartilhado do Nuxt, também conhecido como contexto do Nuxt, que está disponível tanto no lado do cliente quanto no lado do servidor (mas não dentro das rotas Nitro). Ele ajuda você a acessar a instância do aplicativo Vue, hooks de runtime, variáveis de configuração de runtime e estados internos, como ssrContext
e payload
.
const nuxtApp = useNuxtApp()
Se o contexto de runtime não estiver disponível no seu escopo, useNuxtApp
lançará uma exceção quando chamado. Você pode usar tryUseNuxtApp
em vez disso para composables que não requerem nuxtApp
, ou simplesmente para verificar se o contexto está disponível ou não sem uma exceção.
Métodos
provide (name, value)
nuxtApp
é um contexto de runtime que você pode estender usando plugins do Nuxt. Use a função provide
para criar plugins do Nuxt para disponibilizar valores e métodos auxiliares em sua aplicação Nuxt em todos os composables e componentes.
A função provide
aceita os parâmetros name
e value
.
const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)
// Imprime "Hello name!"
console.log(nuxtApp.$hello('name'))
Como você pode ver no exemplo acima, $hello
se tornou a nova parte personalizada do contexto nuxtApp
e está disponível em todos os lugares onde nuxtApp
é acessível.
hook(name, cb)
Os hooks disponíveis em nuxtApp
permitem que você personalize os aspectos de runtime de sua aplicação Nuxt. Você pode usar hooks de runtime em composables Vue.js e plugins do Nuxt para se conectar ao ciclo de vida de renderização.
A função hook
é útil para adicionar lógica personalizada ao se conectar ao ciclo de vida de renderização em um ponto específico. A função hook
é usada principalmente ao criar plugins do Nuxt.
Veja Hooks de Runtime para hooks de runtime disponíveis chamados pelo Nuxt.
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:start', () => {
/* seu código aqui */
})
nuxtApp.hook('vue:error', (..._args) => {
console.log('vue:error')
// if (import.meta.client) {
// console.log(..._args)
// }
})
})
callHook(name, ...args)
callHook
retorna uma promessa quando chamado com qualquer um dos hooks existentes.
await nuxtApp.callHook('my-plugin:init')
Propriedades
useNuxtApp()
expõe as seguintes propriedades que você pode usar para estender e personalizar seu aplicativo e compartilhar estado, dados e variáveis.
vueApp
vueApp
é a instância global do aplicativo Vue.js que você pode acessar através de nuxtApp
.
Alguns métodos úteis:
component()
- Registra um componente global se passar tanto uma string de nome quanto uma definição de componente, ou recupera um já registrado se apenas o nome for passado.directive()
- Registra uma diretiva personalizada global se passar tanto uma string de nome quanto uma definição de diretiva, ou recupera uma já registrada se apenas o nome for passado(exemplo).use()
- Instala um Plugin Vue.js (exemplo).
ssrContext
ssrContext
é gerado durante a renderização no lado do servidor e está disponível apenas no lado do servidor.
Nuxt expõe as seguintes propriedades através de ssrContext
:
url
(string) - URL da solicitação atual.event
(h3js/h3 evento de solicitação) - Acesse a solicitação e resposta da rota atual.payload
(objeto) - Objeto de payload do NuxtApp.
payload
payload
expõe dados e variáveis de estado do lado do servidor para o lado do cliente. As seguintes chaves estarão disponíveis no cliente após serem passadas do lado do servidor:
-
serverRendered
(boolean) - Indica se a resposta é renderizada no lado do servidor. -
data
(objeto) - Quando você busca dados de um endpoint de API usandouseFetch
ouuseAsyncData
, o payload resultante pode ser acessado a partir depayload.data
. Esses dados são armazenados em cache e ajudam a evitar buscar os mesmos dados caso uma solicitação idêntica seja feita mais de uma vez.const { data } = await useAsyncData('count', () => $fetch('/api/count'))
Após buscar o valor de
count
usandouseAsyncData
no exemplo acima, se você acessarpayload.data
, verá{ count: 1 }
registrado lá.Ao acessar o mesmo
payload.data
a partir dessrcontext
, você pode acessar o mesmo valor também no lado do servidor. -
state
(objeto) - Quando você usa o composableuseState
no Nuxt para definir estado compartilhado, esses dados de estado são acessados através depayload.state.[nome-do-seu-estado]
.plugins/my-plugin.tsexport const useColor = () => useState<string>('color', () => 'pink') export default defineNuxtPlugin((nuxtApp) => { if (import.meta.server) { const color = useColor() } })
Também é possível usar tipos mais avançados, como
ref
,reactive
,shallowRef
,shallowReactive
eNuxtError
.Desde o Nuxt v3.4, é possível definir seu próprio reducer/reviver para tipos que não são suportados pelo Nuxt.
No exemplo abaixo, definimos um reducer (ou um serializador) e um reviver (ou desserializador) para a classe DateTime do Luxon, usando um plugin de payload.
plugins/date-time-payload.ts/** * Este tipo de plugin é executado muito cedo no ciclo de vida do Nuxt, antes de revivermos o payload. * Você não terá acesso ao roteador ou outras propriedades injetadas pelo Nuxt. * * Note que a string "DateTime" é o identificador de tipo e deve * ser a mesma tanto no reducer quanto no reviver. */ export default definePayloadPlugin((nuxtApp) => { definePayloadReducer('DateTime', (value) => { return value instanceof DateTime && value.toJSON() }) definePayloadReviver('DateTime', (value) => { return DateTime.fromISO(value) }) })
isHydrating
Use nuxtApp.isHydrating
(boolean) para verificar se o aplicativo Nuxt está hidratando no lado do cliente.
export default defineComponent({
setup (_props, { slots, emit }) {
const nuxtApp = useNuxtApp()
onErrorCaptured((err) => {
if (import.meta.client && !nuxtApp.isHydrating) {
// ...
}
})
}
})
runWithContext
Você provavelmente está aqui porque recebeu uma mensagem de "Instância Nuxt indisponível". Por favor, use este método com moderação e reporte exemplos que estão causando problemas, para que isso possa ser resolvido no nível do framework.
O método runWithContext
é destinado a ser usado para chamar uma função e dar a ela um contexto Nuxt explícito. Normalmente, o contexto Nuxt é passado implicitamente e você não precisa se preocupar com isso. No entanto, ao trabalhar com cenários complexos de async
/await
em middleware/plugins, você pode encontrar instâncias onde a instância atual foi desconfigurada após uma chamada assíncrona.
export default defineNuxtRouteMiddleware(async (to, from) => {
const nuxtApp = useNuxtApp()
let user
try {
user = await fetchUser()
// o compilador Vue/Nuxt perde o contexto aqui por causa do bloco try/catch.
} catch (e) {
user = null
}
if (!user) {
// aplique o contexto Nuxt correto à nossa chamada `navigateTo`.
return nuxtApp.runWithContext(() => navigateTo('/auth'))
}
})
Uso
const result = nuxtApp.runWithContext(() => functionWithContext())
functionWithContext
: Qualquer função que requer o contexto da aplicação Nuxt atual. Este contexto será aplicado corretamente automaticamente.
runWithContext
retornará o que quer que seja retornado por functionWithContext
.
Uma Explicação Mais Profunda do Contexto
A API de Composição do Vue.js (e composables do Nuxt de forma semelhante) funciona dependendo de um contexto implícito. Durante o ciclo de vida, o Vue define a instância temporária do componente atual (e o Nuxt a instância temporária do nuxtApp) para uma variável global e a desconfigura no mesmo tick. Ao renderizar no lado do servidor, há múltiplas solicitações de diferentes usuários e nuxtApp rodando em um mesmo contexto global. Por causa disso, o Nuxt e o Vue imediatamente desconfiguram essa instância global para evitar vazamento de uma referência compartilhada entre dois usuários ou componentes.
O que isso significa? A API de Composição e os Composables do Nuxt estão disponíveis apenas durante o ciclo de vida e no mesmo tick antes de qualquer operação assíncrona:
// --- Vue interno ---
const _vueInstance = null
const getCurrentInstance = () => _vueInstance
// ---
// Vue / Nuxt define uma variável global referenciando o componente atual em _vueInstance ao chamar setup()
async function setup() {
getCurrentInstance() // Funciona
await someAsyncOperation() // Vue desconfigura o contexto no mesmo tick antes da operação assíncrona!
getCurrentInstance() // null
}
A solução clássica para isso é armazenar em cache a instância atual na primeira chamada para uma variável local como const instance = getCurrentInstance()
e usá-la na próxima chamada composable, mas o problema é que qualquer chamada composable aninhada agora precisa aceitar explicitamente a instância como um argumento e não depender do contexto implícito da API de composição. Esta é uma limitação de design com composables e não um problema em si.
Para superar essa limitação, o Vue faz algum trabalho nos bastidores ao compilar nosso código de aplicação e restaura o contexto após cada chamada para <script setup>
:
const __instance = getCurrentInstance() // Gerado pelo compilador Vue
getCurrentInstance() // Funciona!
await someAsyncOperation() // Vue desconfigura o contexto
__restoreInstance(__instance) // Gerado pelo compilador Vue
getCurrentInstance() // Ainda funciona!
Para uma melhor descrição do que o Vue realmente faz, veja unjs/unctx#2 (comentário).
Solução
É aqui que runWithContext
pode ser usado para restaurar o contexto, de forma semelhante a como <script setup>
funciona.
O Nuxt usa internamente unjs/unctx para suportar composables de forma semelhante ao Vue para plugins e middleware. Isso permite que composables como navigateTo()
funcionem sem passar diretamente nuxtApp
para eles - trazendo os benefícios de DX e desempenho da API de Composição para todo o framework Nuxt.
Os composables do Nuxt têm o mesmo design da API de Composição do Vue e, portanto, precisam de uma solução semelhante para fazer essa transformação magicamente. Confira unjs/unctx#2 (proposta), unjs/unctx#4 (implementação da transformação), e nuxt/framework#3884 (Integração ao Nuxt).
Atualmente, o Vue só suporta restauração de contexto assíncrono para <script setup>
para uso de async/await. No Nuxt, o suporte de transformação para defineNuxtPlugin()
e defineNuxtRouteMiddleware()
foi adicionado, o que significa que quando você os usa, o Nuxt os transforma automaticamente com restauração de contexto.
Problemas Restantes
A transformação unjs/unctx
para restaurar automaticamente o contexto parece ter bugs com declarações try/catch
contendo await
, o que precisa ser resolvido para remover a necessidade da solução alternativa sugerida acima.
Contexto Assíncrono Nativo
Usando um novo recurso experimental, é possível habilitar o suporte a contexto assíncrono nativo usando Node.js AsyncLocalStorage
e o novo suporte unctx para tornar o contexto assíncrono disponível nativamente para qualquer composable assíncrono aninhado sem precisar de uma transformação ou passagem/chamada manual com contexto.
O suporte a contexto assíncrono nativo funciona atualmente no Bun e no Node.
tryUseNuxtApp
Esta função funciona exatamente da mesma forma que useNuxtApp
, mas retorna null
se o contexto não estiver disponível em vez de lançar uma exceção.
Você pode usá-la para composables que não requerem nuxtApp
, ou simplesmente para verificar se o contexto está disponível ou não sem uma exceção.
Exemplo de uso:
export function useStandType() {
// Sempre funciona no cliente
if (tryUseNuxtApp()) {
return useRuntimeConfig().public.STAND_TYPE
} else {
return process.env.STAND_TYPE
}
}
※Esta página é uma tradução não oficial da documentação oficial do Nuxt.js.
A página correspondente na documentação oficial está aqui:
https://nuxt.com/docs/3.x/api/composables/use-nuxt-app