Explication détaillée de l'utilisation de Pinia dans Vue3

Introduction

Pinia est une bibliothèque de gestion d'état conçue spécifiquement pour Vue.js, qui offre un moyen simple et intuitif de gérer l'état de l'application. Lors de l'utilisation de Pinia, il est facile de créer un magasin qui définit l'état, puis de le lier aux composants Vue pour leur permettre de consommer cet état. Comparé à Vuex mentionné dans le blog précédent, Pinia est plus facile à utiliser, de plus petite taille et dispose d'un meilleur support TypeScript et d'un système de plug-in.

Sur le site officiel de Vue.js, on peut voir que Pinia a remplacé Vuex et fait désormais partie de l'écosystème Vue.

Installer et configurer Pinia

L'installation et la configuration de Pinia sont très simples. Comme les autres plugins Vue, Pinia doit être installé via yarn ou npm et fourni avec l'application Vue. Vous pouvez utiliser la commande suivante pour l'installation :

yarn add pinia
# 或者使用 npm
npm install pinia

Après avoir installé le package Pinia, vous devez importer la fonction createPinia dans le fichier main.ts et lier le plugin Pinia à l'application Vue, comme suit :

import {
    
     createApp } from 'vue';
import {
    
     createPinia } from 'pinia';
import App from './App.vue';

const app = createApp(App);

const pinia = createPinia();
app.use(pinia);

app.mount('#app');

Utilisez la fonction createPinia() pour créer et initialiser une instance de plugin Pinia, et liez-la à l'application Vue en utilisant app.use(pinia). À ce stade, nous pouvons utiliser Pinia pour gérer l'état de l'application Vue.

Le noyau de Pinia

Magasin

Le magasin est le concept de base de la gestion de l'état dans Pinia. Il équivaut à l'état d'un composant Vue, mais le magasin est un module distinct.

Store est défini avec defineStore(), son premier paramètre nécessite un nom unique, ce nom, également utilisé comme id, doit être passé, Pinia l'utilisera pour connecter store et devtools. Afin de développer l'usage habituel, nommer la fonction retournée use... est une convention conforme au style de la fonction compositionnelle.

Le second paramètre de defineStore() peut accepter deux types de valeurs : une fonction Setup ou un objet Option.

Exemple de code définissant Store :

import {
    
     defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore``useCartStore``useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {
    
    
  // 其他配置...
})

État

L'état est l'endroit où les données sont stockées dans le magasin. En définissant State, les données peuvent être consultées et modifiées n'importe où dans le magasin.

Dans Pinia, l'état est défini comme une fonction qui renvoie l'état initial. Cela permet à Pinia de prendre en charge à la fois le serveur et le client.
L'exemple de code pour définir State est le suivant :

import {
    
     defineStore } from 'pinia'

const useStore = defineStore('storeId', {
    
    
  // 为了完整类型推理,推荐使用箭头函数
  state: () => {
    
    
    return {
    
    
      // 所有这些属性都将自动推断出它们的类型
      count: 0,
      name: 'Eduardo',
      isAdmin: true,
      items: [],
      hasChanged: true,
    }
  },
})

Getter

Getter est utilisé pour obtenir des données dérivées de l'état, similaires aux propriétés calculées dans les composants Vue. Ils peuvent être définis via la propriété getters dans defineStore(). Les fonctions fléchées sont recommandées et recevront l'état comme premier argument :

export const useStore = defineStore('main', {
    
    
  state: () => ({
    
    
    count: 0,
  }),
  getters: {
    
    
    doubleCount: (state) => state.count * 2,
  },
})

Action

Les actions sont équivalentes aux méthodes dans les composants. Ils peuvent être définis via l'attribut actions dans defineStore() ; Action est un moyen d'encapsuler des opérations asynchrones dans le magasin. C'est une fonction qui peut être appelée, et peut également recevoir des paramètres et modifier l'état dans le magasin. Les actions doivent toujours être synchrones et renvoyer une promesse afin que les résultats soient correctement gérés lors du traitement d'opérations asynchrones.

Les actions dans Pinia sont créées par defineStore et peuvent être utilisées en les définissant dans des actions. Par exemple, voici une définition d'action dans un magasin :

import {
    
     defineStore } from 'pinia'

export const myStore = defineStore('myStore',{
    
     
  state: () => ({
    
    
    message: 'Hello',
  }),
  actions: {
    
    
    async fetchMessage() {
    
    
      const response = await fetch('http://127.0.0.1:5173/message')
      const data = await response.json()
      this.message = data.message
    },
  },
})

Dans l'exemple ci-dessus, nous définissons une action pour myStore, fetchMessage(), qui récupère les données de l'API d'arrière-plan et met à jour l'état dans le magasin. On peut alors appeler cette Action depuis un composant ou une autre Action :

import {
    
     useStore } from 'pinia'

export default {
    
    
  setup() {
    
    
    const store = useStore('myStore')

    function handleClick() {
    
    
      store.fetchMessage()
    }

    return {
    
    
      handleClick,
    }
  },
}

Dans le code ci-dessus, nous utilisons le crochet useStore dans le composant pour obtenir l'instance de magasin, puis nous le transmettons à la méthode fetchMessage(). Cette méthode récupère les données de l'arrière-plan de l'application et met à jour l'état en mémoire. Enfin, une méthode handleClick() est exposée afin que le composant puisse l'appeler et déclencher l'action.

Créer et utiliser Pinia

Créer des Pinias

Nous avons déjà installé et configuré Pinia. Avant de créer Pinia, pour une gestion et une maintenabilité unifiées du code, nous créons toujours d'abord un dossier de magasin, puis créons Pinia associé. Les étapes spécifiques sont les suivantes

  1. Créez un nouveau dossier de magasin sous le dossier src, et tous les codes suivants qui nécessitent Pinia pour la gestion de l'état sont placés dans ce dossier
  2. Créez un nouveau fichier movieListStore.js sous le dossier du magasin. Une fois la création terminée, ouvrez le fichier
  3. Introduire la méthode defineStore dans Pinia dans le fichier movieListStore.js
import {
    
     defineStore } from 'pinia'
  1. Créez un objet defineStore, définissez un useMovieListStore pour recevoir l'objet créé par defineStore et exportez-le via l'exportation par défaut
 const useMovieListStore = defineStore('movie',{
    
     
  state: () => ({
    
    
    isShow: true,
    movies: [],
  }),
  getters: {
    
    
    getIsShow() {
    
    
      return this.isShow
    },
    getMovies() {
    
    
      return this.movies
    },
  },
  actions: {
    
    
    setIsShow(value) {
    
    
      this.isShow = value
    },
    async fetchMovies() {
    
    
      const response = await fetch('https://api.movies.com/movies')
      const data = await response.json()
      this.movies = data
    },
  },
})
export default useMovieListStore 

Dans le code ci-dessus, nous utilisons action pour définir deux méthodes, une méthode synchrone setIsShow et
une méthode asynchrone fetchMovies
Remarque :
Il convient de noter ici que la suggestion officielle est que lors de la définition de la fonction hook, il est recommandé d'utiliser la méthode de dénomination au début de l'utilisation et à la fin de Store. Nommez l'objet créé ci-dessus, comme useMovieListStore ci-dessus

Utiliser Pinia

Nous avons créé Pinia plus tôt, puis nous pouvons l'utiliser dans des composants.
Pour utiliser le magasin dans un composant Vue, nous devons accéder à l'instance du magasin via la fonction useStore().
Les étapes pour utiliser Pinia dans les composants Vue sont les suivantes

  1. Utilisez d'abord l'importation pour introduire useStore dans Pinia
import {
    
     useStore } from 'pinia'
  1. Créer un objet useStore
const store = useStore('movie')
  1. Obtenez le statut via le store.getIsShow() défini ci-dessus où vous devez obtenir le statut
return {
    
    
   isShow: store.getIsShow(),
}

L'exemple de code complet dans Menu.vue est le suivant :

<template>
  <nav>
    <ul>
      <li v-show="isShow">{
    
    {
    
     $route.name }} </li>
      <li><router-link to="/">Home</router-link></li>
      <li><router-link to="/movies">Movies</router-link></li>
    </ul>
  </nav>
</template>

<script>
import {
    
     defineComponent } from 'vue'
import {
    
     useStore } from 'pinia'

export default defineComponent({
    
    
  name: 'Menu',

  setup() {
    
    
    const store = useStore('movie')

    return {
    
    
      isShow: store.getIsShow(),
    }
  },
})
</script>

La méthode Option Store de Pinia définit Store

La façon dont le magasin d'options définit le magasin est similaire à l'API d'options de Vue. Nous le définissons en transmettant un objet Option avec des propriétés d'état, d'actions et de getters. L'exemple de code est le suivant :

export const useCounterStore = defineStore('counter', {
    
    
  state: () => ({
    
     count: 0 }),
  getters: {
    
    
    double: (state) => state.count * 2,
  },
  actions: {
    
    
    increment() {
    
    
      this.count++
    },
  },
})

Nous pouvons considérer l'état comme les données du magasin (données), les getters comme les propriétés calculées du magasin (calculées) et les actions comme les méthodes (méthodes).

La méthode Setup Store de Pinia définit Store

Le magasin d'installation est légèrement différent du magasin d'options. Il est similaire à la fonction de configuration de l'API composite Vue. Nous passons une fonction qui définit certaines propriétés et méthodes réactives et renvoie une fonction avec les propriétés et les méthodes que nous voulons exposer. . objet méthode. L'exemple de code est le suivant :

export const useCounterStore = defineStore('counter', () => {
    
    
  const count = ref(0)
  function increment() {
    
    
    count.value++
  }

  return {
    
     count, increment }
})

Dans le magasin de configuration :

  • ref() est l'attribut d'état
  • calculated() est des getters
  • fonction () est des actions

exemple de code

Voici un exemple pour illustrer pleinement l'utilisation de la gestion d'état Pinia. Maintenant, les effets suivants doivent être obtenus :
Deux fonctions doivent être complétées sur la page. Une fonction est de contrôler le saut de différentes pages en surveillant la valeur de isShow , et la barre de menu inférieure L'affichage et le masquage des boutons ; une autre fonction consiste à se connecter au réseau via une fonction pour obtenir la liste des films et l'afficher sur la page de détails

Dans l'API facultative, le code d'implémentation est le suivant :

  1. Code dans main.js
// main.js

import {
    
     createApp } from 'vue'
import App from './App.vue'
import {
    
     createPinia } from 'pinia'
import {
    
     movieStore } from './store/movieStore'

const app = createApp(App)

app.use(createPinia())
app.use(movieStore)

app.mount('#app')
  1. Le code dans movieStore.js sous le dossier store
// store/movieStore.js

import {
    
     defineStore } from 'pinia'

export const useMovieListStore = defineStore('movie',{
    
     
  state: () => ({
    
    
    isShow: true,
    movies: [],
  }),
  getters: {
    
    
    getIsShow() {
    
    
      return this.isShow
    },
    getMovies() {
    
    
      return this.movies
    },
  },
  actions: {
    
    
    setIsShow(value) {
    
    
      this.isShow = value
    },
    async fetchMovies() {
    
    
      const response = await fetch('https://api.movies.com/movies')
      const data = await response.json()
      this.movies = data
    },
  },
})
  1. Le code du fichier Menu.vue sous le dossier des composants
<!-- components/Menu.vue -->

<template>
  <nav>
    <ul>
      <li v-show="isShow">{
    
    {
    
     $route.name }} </li>
      <li><router-link to="/">Home</router-link></li>
      <li><router-link to="/movies">Movies</router-link></li>
    </ul>
  </nav>
</template>

<script>
import {
    
     defineComponent } from 'vue'
import {
    
     useStore } from 'pinia'

export default defineComponent({
    
    
  name: 'Menu',

  setup() {
    
    
    const store = useStore('movie')

    return {
    
    
      isShow: store.getIsShow(),
    }
  },
})
</script>
  1. Le code de MovieList.vue sous le dossier composants
<!-- components/MovieList.vue -->

<template>
  <ul>
    <li v-for="movie in movies" :key="movie.id">
      <router-link :to="`/movies/${
      
      movie.id}`">{
    
    {
    
     movie.title }}</router-link>
    </li>
  </ul>
</template>

<script>
import {
    
     defineComponent } from 'vue'
import {
    
     useStore } from 'pinia'

export default defineComponent({
    
    
  name: 'MovieList',

  setup() {
    
    
    const store = useStore('movie')

    store.fetchMovies()

    return {
    
    
      movies: store.getMovies(),
    }
  },
})
</script>
  1. Le code de MovieDetails.vue sous le dossier views
<!-- views/MovieDetails.vue -->

<template>
  <div v-if="movie">
    <h2>{
    
    {
    
     movie.title }}</h2>
    <p>{
    
    {
    
     movie.description }} </p>
  </div>
  <div v-else>
    <h2>Movie Not Found</h2>
  </div>
</template>

<script>
import {
    
     defineComponent } from 'vue'
import {
    
     useRoute } from 'vue-router'
import {
    
     useStore } from 'pinia'

export default defineComponent({
    
    
  name: 'MovieDetails',

  setup() {
    
    
    const route = useRoute()
    const store = useStore('movie')
    const movieId = route.params.id
    const movie = store.getMovies().find((movie) => movie.id === movieId)

    return {
    
    
      movie,
    }
  },
})
</script>

Le code ci-dessus montre comment partager et gérer l'état à l'aide de store, getter et action dans Pinia. Parmi eux, movieStore définit un magasin contenant deux états de isShow et de films, et une action pour modifier isShow et obtenir la liste des films. Dans le composant Menu.vue, nous utilisons le crochet useStore pour obtenir l'état isShow du magasin et contrôler l'affichage et le masquage du bouton de la barre de menu inférieure en fonction de sa valeur. Dans le composant MovieList.vue, nous utilisons le crochet useStore pour obtenir l'état des films à partir du magasin et l'action fetchMovies() pour récupérer la liste des films à partir du réseau. Dans le composant MovieDetails.vue, nous utilisons le crochet useRoute pour obtenir l'identifiant du paramètre de routage de la page actuelle, utilisons le crochet useStore pour obtenir le statut des films à partir du magasin et obtenons les informations détaillées du film actuel selon le movieId et getMovies() accesseur.

Notez que dans le crochet setup (), nous utilisons le crochet useStore pour obtenir l'état et effectuer des opérations à partir du magasin. Étant donné que le crochet useStore renvoie un proxy réactif, nous n'avons pas besoin de mettre à jour manuellement l'état de manière réactive. De plus, nous pouvons dissocier les composants du magasin, ce qui facilite leur test et leur réutilisation.

Dans l'API combinée, le code d'implémentation est légèrement différent. Ici, nous ne prenons que la page MovieList.vue comme exemple. Les autres pages sont écrites de manière similaire et ne seront pas affichées. Le code de la page MovieList.vue est le suivant :

<!-- components/MovieList.vue -->

<template>
  <ul>
    <li v-for="movie in movies" :key="movie.id">
      <router-link :to="`/movies/${
      
      movie.id}`">{
    
    {
    
     movie.title }}</router-link>
    </li>
  </ul>
</template>

<script setup>
import {
    
     onMounted, computed } from 'vue'
import {
    
     useStore } from 'pinia'

const store = useStore('movie')

onMounted(() => {
  store.fetchMovies()
})

const movies = computed(() => store.getMovies())
</script>

OK, c'est la fin de l'introduction sur l'utilisation de Pinia pour la gestion globale des états dans Vue3. Si vous l'aimez, aimez-le et suivez-le dans vos favoris !

Je suppose que tu aimes

Origine blog.csdn.net/w137160164/article/details/131160122
conseillé
Classement