nuxt logo

Traducción de Documentación (No Oficial)

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.

Ver también api > composables > use-state

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.

app.vue
<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>
Editar y previsualizar el código de ejemploexamples > features > state-management

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.

app.vue
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.

Ver también api > utils > call-once

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)))
}
Editar y previsualizar el código de ejemploexamples > advanced > locale

Estado Compartido

Usando composables auto-importados podemos definir estados globales con tipos seguros e importarlos en toda la aplicación.

composables/states.ts
export const useColor = () => useState<string>('color', () => 'pink')
app.vue
<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