Fermer

août 7, 2025

Déverrouiller le partage de données dans votre application Nuxt

Déverrouiller le partage de données dans votre application Nuxt


Nuxt fait du partage de données entre les composants un cliché. Regardons Usestate, Uselocalstate et UseCookie.

J’ai été obsédé par useState Dans Nuxt depuis la première fois, je l’ai vu. D’autres cadres ne semblent pas partager des données aussi facilement (vous en regardant, réagissez le contexte). Nuxt a de nombreuses options pour stocker l’état, et cela facilite certainement ces choses. Je l’aime tellement, j’ai même écrit des versions pour Autres cadres.

TL; Dr

Nuxt est le cadre le plus simple pour partager les données entre les composants. Vous pouvez utiliser useState, provide et injectou persistent les données à travers les cookies avec useCookie. Quoi qu’il en soit, aucun autre cadre ne le rend facile.

L’Usstate

Ne confondez pas les nux useState Avec React’s useState. La version de React est beaucoup plus faible. L’USESTATE de Nuxt, en revanche, est génial!

Comment ça marche

Disons que nous voulons partager des données entre les composants. Dans d’autres cadres, y compris Vue lui-même, vous devez propulser des données partagées de forage. Ce n’est pas amusant. Le contexte, en revanche, vous permet de partager des données en définissant une paire «clé / valeur» et en l’utilisant n’importe où. Nuxt fait cela automatiquement.

useState('count', () => 0)

Le premier paramètre est la clé. Dans n’importe quel cadre avec un type de API de contexte Vous devez définir une clé pour obtenir une valeur. Le deuxième paramètre est le secours. Le secours est utilisé lorsqu’il n’y a pas de valeur appartenant à cette clé; Cependant, il est également utilisé pour stocker la valeur initiale elle-même.

Usage

La façon recommandée de l’utiliser est de créer un crochet personnalisé ou un composable personnalisé.

export function useCount() {

	return useState('count', () => 0)
	
}

Cela renvoie un compteur réactif qui peut être utilisé n’importe où!

Je sais ce que tu penses. Pourquoi ne pas simplement utiliser une variable réactive normale?

export function useCount() {
	
	return ref(0)

}

Cela semble logique, mais si vous utilisez useCount Dans plusieurs composants, l’État n’est pas partagé. Vous aurez de nouveaux compteurs pour chaque implémentation.

// component 1

<script setup lang="ts">
const count = useCount()
</script>

<template>
  <p>Count: {{ count }}</p>
  <button
    @click="
      () => {
        count++;
      }
    "
  >
    +
  </button>
</template>

// component 2
<script setup lang="ts">
const count = useCount()
</script>

<template>
<div> {{ count }} <div>
</template>

Si nous cliquons sur le bouton, nous voulons le compteur à l’incrément partout.

Comment ça marche vraiment?

Je suis devenu tellement obsédé par la simplicité, j’ai recherché le code source.

Global vs local

Nuxt a un magasin mondial. Vous pouvez obtenir les valeurs n’importe où useNuxtApp().

export function useGlobalState<T>(key: string, init?: (() => T | Ref<T>)) {

    const nuxtApp = useNuxtApp()

    const state = toRef(nuxtApp.payload.state, key)

    if (state.value === undefined && init) {

        const initialValue = init()

        state.value = initialValue
    }
    return state
}

J’ai créé une version très simplifiée, mais fonctionnelle, de useState(). Vous obtenez la valeur de la boutique mondiale, faites-la réactive et renvoyez-la. S’il n’existe pas, créez-le, enregistrez-le, renvoyez-le.

export function useCount() {

	return useGlobalState('count', () => 0)

}

Cela fonctionnera exactement de la même manière que useState. Parce qu’il ne fonctionne qu’une seule fois, il s’appelle un singleton.

uselocalstate

Mais que se passe-t-il si vous avez besoin d’une version locale?

Usage

Parfois, vous ne voulez pas enregistrer chaque valeur d’état pour le magasin mondial. Cela peut rendre difficile de faire des tests de composants individuels, de créer des composants portables ou isolés et de conserver les données encapsulées.

Fournir / injecter

Inspiré par Angular, vous pouvez définir et obtenir un contexte facilement dans Vue / Nuxt en fournissant et en injectant.

provide(key, value)

inject(key, fallback_value)

Parfois, vous pouvez voir les modèles:

export function setCount(initialValue: number) {
	const count = ref(initialValue)
	provide('count', count)
	return count
}

export function getCount() {
	return inject<Ref<number>>('count');
}	

Généralement, vous définissez et obtenez les éléments dans différents composants. Cependant, je ne vois pas pourquoi nous ne pouvons pas faire le même schéma que useState Ici aussi.

Locale

export function useLocalState<T>(key: string, init?: (() => T | Ref<T>)) {

    const state = inject(key, undefined)

    if (state === undefined && init) {

        const initialValue = toRef(init())

        provide(key, initialValue)

        return initialValue
    }
    return state
}

Maintenant, nous pouvons définir n’importe quel état localement, tout comme useState.

Mise en garde

L’État doit pouvoir parler à l’autre État dans une ligne. Cela signifie qu’il doit être imbriqué. Si je crée deux composants enfants et que je définis le premier composant avec le compteur, le deuxième composant Ne va pas être capable de communiquer avec l’autre composant enfant. Le contexte est partagé hiérarchique, pas entre les frères et sœurs.

<Count />

<Count />

Cependant, vous pouvez initialiser le compteur dans n’importe quel parent afin qu’il y ait tous deux accès.

<script setup lang="ts">
useLocalState("count", () => 0);
</script>

<template>
  <Count />
  <Count />
</template>

Maintenant vous pouvez utiliser useLocalState('count') n’importe où chez les enfants.

usecookie

Nuxt a également une façon magique d’obtenir et de définir des cookies sur le frontend comme tout autre signal avec ref.

const count = useCookie("count");

count.value = 10;

Cela sauvera la valeur à 10 et créer le cookie.

valeur 10

Vous pouvez utiliser la valeur comme n’importe quelle autre référence. La beauté de ceci est: elle persistera! Vous n’enregistrez pas seulement une valeur globale, mais vous l’enregistrez au cookie.

Défaut

Il existe un tas d’options de cookie que vous pouvez définir, mais pour définir la valeur par défaut, vous définissez une fonction dans default comme tu le ferais avec useState.

const count = useCookie("count", {
  default: () => 10
});

Bonus: sous le capot

Les cookies sont une créature complexe, mais pour des raisons d’explication, j’ai pensé créer une version pseudocode à partir du code source. Cela nécessiterait quelque chose d’aussi complexe que l’original pour fonctionner correctement, mais vous obtenez l’essentiel.

export function useCookie(key, { default: init() }) {
  
  if (server) {
	  const cookie = getServerCookie()
	  if (cookie) {
	    return getCookie(key)
	  }
	  const state = init()
	  setCookie(key, state)
	  return state
	}
	
	// browser	
	const cookie = getClientCookie()
	if (cookie) {
		return getCookie(key)
	}
	const state = init()
	setCookie(key, state)
	return toRef(state)

// !!! NOT REAL CODE, WILL NOT WORK

L’enregistrement des données n’a jamais été aussi facile!

Démo: Vercel
Repo: Girub




Source link