Gestión de Estado
Nuxt proporciona potentes bibliotecas de gestión de estado y el composable useState para crear un estado compartido reactivo y compatible con SSR.
Nuxt proporciona el composable useState
para crear un estado compartido reactivo y compatible con SSR entre componentes.
useState
es un reemplazo de ref
compatible con SSR. Su valor se preservará después del renderizado del lado del servidor (durante la hidratación del lado del cliente) y se compartirá entre todos los componentes usando una clave única.
Debido a que los datos dentro de useState
se serializarán a JSON, es importante que no contengan nada que no pueda ser serializado, como clases, funciones o símbolos.
Mejores Prácticas
Nunca definas const state = ref()
fuera de <script setup>
o de la función setup()
.
Por ejemplo, hacer export myState = ref({})
resultaría en un estado compartido entre solicitudes en el servidor y puede llevar a fugas de memoria.
En su lugar, usa const useX = () => useState('x')
Ejemplos
Uso Básico
En este ejemplo, usamos un estado de contador local al componente. Cualquier otro componente que use useState('counter')
comparte el mismo estado reactivo.
<script setup lang="ts">
const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script>
<template>
<div>
Contador: {{ counter }}
<button @click="counter++">
+
</button>
<button @click="counter--">
-
</button>
</div>
</template>
Para invalidar globalmente el estado en caché, consulta el utilitario clearNuxtState
.
Inicializando el Estado
La mayoría de las veces, querrás inicializar tu estado con datos que se resuelven de manera asíncrona. Puedes usar el componente app.vue
con el utilitario callOnce
para hacerlo.
const websiteConfig = useState('config')
await callOnce(async () => {
websiteConfig.value = await $fetch('https://my-cms.com/api/website-config')
})
Esto es similar a la acción nuxtServerInit
en Nuxt 2, que permite llenar el estado inicial de tu tienda del lado del servidor antes de renderizar la página.
Uso con Pinia
En este ejemplo, aprovechamos el módulo Pinia para crear una tienda global y usarla en toda la aplicación.
Asegúrate de instalar el módulo Pinia con npx nuxt module add pinia
o sigue los pasos de instalación del 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 Avanzado
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 Compartido
Usando composables auto-importados podemos definir estados globales con tipos seguros e importarlos en toda la aplicación.
export const useColor = () => useState<string>('color', () => 'pink')
<script setup lang="ts">
// ---cut-start---
const useColor = () => useState<string>('color', () => 'pink')
// ---cut-end---
const color = useColor() // Igual que useState('color')
</script>
<template>
<p>Color actual: {{ color }}</p>
</template>
Uso de bibliotecas de terceros
Nuxt solía depender de la biblioteca Vuex para proporcionar gestión de estado global. Si estás migrando desde Nuxt 2, por favor dirígete a la guía de migración.
Nuxt no tiene una opinión estricta sobre la gestión de estado, así que siéntete libre de elegir la solución adecuada para tus necesidades. Hay múltiples integraciones con las bibliotecas de gestión de estado más populares, incluyendo:
- Pinia - la recomendación oficial de Vue
- Harlem - gestión de estado global inmutable
- XState - enfoque de máquina de estados con herramientas para visualizar y probar tu lógica de estado
※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/getting-started/state-management