Gerenciamento de Estado
O Nuxt fornece bibliotecas poderosas de gerenciamento de estado e o composable useState para criar um estado compartilhado reativo e amigável ao SSR.
O Nuxt fornece o composable useState
para criar um estado compartilhado reativo e amigável ao SSR entre componentes.
useState
é uma substituição amigável ao SSR para ref
. Seu valor será preservado após a renderização do lado do servidor (durante a hidratação do lado do cliente) e compartilhado entre todos os componentes usando uma chave única.
Como os dados dentro de useState
serão serializados para JSON, é importante que não contenham nada que não possa ser serializado, como classes, funções ou símbolos.
Melhores Práticas
Nunca defina const state = ref()
fora de <script setup>
ou da função setup()
.
Por exemplo, fazer export myState = ref({})
resultaria em estado compartilhado entre requisições no servidor e pode levar a vazamentos de memória.
Em vez disso, use const useX = () => useState('x')
Exemplos
Uso Básico
Neste exemplo, usamos um estado de contador local ao componente. Qualquer outro componente que use useState('counter')
compartilha o mesmo estado reativo.
<script setup lang="ts">
const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script>
<template>
<div>
Counter: {{ counter }}
<button @click="counter++">
+
</button>
<button @click="counter--">
-
</button>
</div>
</template>
Para invalidar globalmente o estado em cache, veja o utilitário clearNuxtState
.
Inicializando o Estado
Na maioria das vezes, você vai querer inicializar seu estado com dados que são resolvidos de forma assíncrona. Você pode usar o componente app.vue
com o utilitário callOnce
para fazer isso.
const websiteConfig = useState('config')
await callOnce(async () => {
websiteConfig.value = await $fetch('https://my-cms.com/api/website-config')
})
Isso é semelhante à ação nuxtServerInit
no Nuxt 2, que permite preencher o estado inicial da sua loja no lado do servidor antes de renderizar a página.
Uso com Pinia
Neste exemplo, aproveitamos o módulo Pinia para criar uma loja global e usá-la em todo o aplicativo.
Certifique-se de instalar o módulo Pinia com npx nuxt module add pinia
ou siga as etapas de instalação do módulo.
export const useWebsiteStore = defineStore('websiteStore', {
state: () => ({
name: '',
description: ''
}),
actions: {
async fetch() {
const infos = await $fetch('https://api.nuxt.com/modules/pinia')
this.name = infos.name
this.description = infos.description
}
}
})
Uso Avançado
import type { Ref } from 'vue'
export const useLocale = () => {
return useState<string>('locale', () => useDefaultLocale().value)
}
export const useDefaultLocale = (fallback = 'en-US') => {
const locale = ref(fallback)
if (import.meta.server) {
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
if (reqLocale) {
locale.value = reqLocale
}
} else if (import.meta.client) {
const navLang = navigator.language
if (navLang) {
locale.value = navLang
}
}
return locale
}
export const useLocales = () => {
const locale = useLocale()
const locales = ref([
'en-US',
'en-GB',
...
'ja-JP-u-ca-japanese'
])
if (!locales.value.includes(locale.value)) {
locales.value.unshift(locale.value)
}
return locales
}
export const useLocaleDate = (date: Ref<Date> | Date, locale = useLocale()) => {
return computed(() => new Intl.DateTimeFormat(locale.value, { dateStyle: 'full' }).format(unref(date)))
}
Estado Compartilhado
Usando composables auto-importados, podemos definir estados globais com tipagem segura e importá-los em todo o aplicativo.
export const useColor = () => useState<string>('color', () => 'pink')
<script setup lang="ts">
// ---cut-start---
const useColor = () => useState<string>('color', () => 'pink')
// ---cut-end---
const color = useColor() // Mesmo que useState('color')
</script>
<template>
<p>Cor atual: {{ color }}</p>
</template>
Usando bibliotecas de terceiros
O Nuxt costumava depender da biblioteca Vuex para fornecer gerenciamento de estado global. Se você está migrando do Nuxt 2, por favor, consulte o guia de migração.
O Nuxt não tem uma opinião rígida sobre o gerenciamento de estado, então sinta-se à vontade para escolher a solução certa para suas necessidades. Existem múltiplas integrações com as bibliotecas de gerenciamento de estado mais populares, incluindo:
- Pinia - a recomendação oficial do Vue
- Harlem - gerenciamento de estado global imutável
- XState - abordagem de máquina de estados com ferramentas para visualizar e testar sua lógica de estado
※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/getting-started/state-management