Explicación detallada del uso de Pinia en Vue3

Introducción

Pinia es una biblioteca de administración de estado diseñada específicamente para Vue.js, que brinda una manera fácil e intuitiva de administrar el estado de la aplicación. Al usar Pinia, es fácil crear una tienda que defina el estado y luego vincularla con los componentes de Vue para permitirles consumir ese estado. En comparación con Vuex mencionado en el blog anterior, Pinia es más fácil de usar, más pequeño en tamaño y tiene mejor compatibilidad con TypeScript y un sistema de complementos.

En el sitio web oficial de Vue.js, podemos ver que Pinia ha reemplazado a Vuex y se ha convertido en parte del ecosistema de Vue.

Instalar y configurar Pinia

Instalar y configurar Pinia es muy simple. Al igual que otros complementos de Vue, Pinia debe instalarse a través de yarn o npm y se incluye con la aplicación Vue. Puede usar el siguiente comando para instalar:

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

Después de instalar el paquete Pinia, debe importar la función createPinia en el archivo main.ts y vincular el complemento Pinia con la aplicación Vue, de la siguiente manera:

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');

Utilice la función createPinia() para crear e inicializar una instancia del complemento Pinia y vincularla a la aplicación Vue mediante app.use(pinia). En este punto, podemos usar Pinia para administrar el estado de la aplicación Vue.

Núcleo de Pinia

Almacenar

La tienda es el concepto central de la gestión estatal en Pinia. Es equivalente al estado en un componente de Vue, pero Store es un módulo separado.

La tienda se define con defineStore(), su primer parámetro requiere un nombre único, este nombre, que también se usa como id, debe pasarse, Pinia lo usará para conectar la tienda y las herramientas de desarrollo. Para desarrollar el uso habitual, nombrar la función devuelta use... es una convención que se ajusta al estilo de la función compositiva.

El segundo parámetro de defineStore() puede aceptar dos tipos de valores: una función de configuración o un objeto de opción.

Código de ejemplo que define la tienda:

import {
    
     defineStore } from 'pinia'

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

Estado

El estado es donde se almacenan los datos en el almacén. Al definir Estado, se puede acceder a los datos y modificarlos en cualquier parte del almacén.

En Pinia, el estado se define como una función que devuelve el estado inicial. Esto permite que Pinia sea compatible tanto con el servidor como con el cliente.
El código de muestra para definir State es el siguiente:

import {
    
     defineStore } from 'pinia'

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

Adquiridor

Getter se usa para obtener datos derivados del estado, similar a las propiedades calculadas en los componentes de Vue. Se pueden definir a través de la propiedad getters en defineStore(). Se recomiendan las funciones de flecha y recibirán el estado como primer argumento:

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

Acción

Las acciones son equivalentes a los métodos en los componentes. Se pueden definir a través del atributo actions en defineStore(); Action es una forma de encapsular operaciones asíncronas en la tienda.Es una función que se puede llamar, y también puede recibir parámetros y modificar el estado en la tienda. Las acciones siempre deben ser sincrónicas y devolver una promesa para que los resultados se manejen correctamente al procesar operaciones asincrónicas.

Las acciones en Pinia son creadas por defineStore y se pueden usar definiéndolas en acciones. Por ejemplo, aquí hay una definición de Acción en una tienda:

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
    },
  },
})

En el ejemplo anterior, definimos una Acción para myStore, fetchMessage(), que obtendrá datos de la API en segundo plano y actualizará el estado en la tienda. Entonces podemos llamar a esta Acción desde un componente u otra Acción:

import {
    
     useStore } from 'pinia'

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

    function handleClick() {
    
    
      store.fetchMessage()
    }

    return {
    
    
      handleClick,
    }
  },
}

En el código anterior, usamos el gancho useStore en el componente para obtener la instancia de la tienda y luego la pasamos al método fetchMessage(). Este método obtendrá datos del fondo de la aplicación y actualizará el estado en la memoria. Finalmente, se expone un método handleClick() para que el componente pueda llamarlo y desencadenar la acción.

Crea y usa Pinia

Crear pinias

Hemos instalado y configurado Pinia antes. Antes de crear Pinia, para la gestión unificada y la capacidad de mantenimiento del código, primero creamos una carpeta de almacenamiento y luego creamos Pinia relacionado. Los pasos específicos son los siguientes

  1. Cree una nueva carpeta de almacenamiento en la carpeta src y todos los códigos posteriores que requieran Pinia para la gestión del estado se colocarán en esta carpeta.
  2. Cree un nuevo archivo movieListStore.js en la carpeta de la tienda. Una vez completada la creación, abra el archivo
  3. Introduzca el método defineStore en Pinia en el archivo movieListStore.js
import {
    
     defineStore } from 'pinia'
  1. Cree un objeto defineStore, defina un useMovieListStore para recibir el objeto creado por defineStore y expórtelo a través de la exportación predeterminada
 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 

En el código anterior, usamos action para definir dos métodos, un método síncrono setIsShow y
un método asíncrono fetchMovies al comienzo del uso y al final de Store. Asigne un nombre al objeto creado anteriormente, como useMovieListStore arriba

Usa Pinia

Hemos creado Pinia anteriormente y luego podemos usarlo en componentes.
Para usar la tienda en un componente de Vue, necesitamos acceder a la instancia de la tienda a través de la función useStore().
Los pasos para usar Pinia en los componentes de Vue son los siguientes

  1. Primero use import para introducir useStore en Pinia
import {
    
     useStore } from 'pinia'
  1. Crear un objeto useStore
const store = useStore('movie')
  1. Obtenga el estado a través de store.getIsShow() definido anteriormente donde necesita obtener el estado
return {
    
    
   isShow: store.getIsShow(),
}

El código de muestra completo en Menu.vue es el siguiente:

<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>

El método Option Store de Pinia define Store

La forma de la Tienda de Opciones para definir la Tienda es similar a la API de opciones de Vue. Lo definimos pasando un objeto de Opción con propiedades de estado, acciones y captadores. El código de ejemplo es el siguiente:

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

Podemos pensar en el estado como los datos de la tienda (datos), los captadores como las propiedades calculadas de la tienda (computadas) y las acciones como los métodos (métodos).

El método Setup Store de Pinia define Store

La tienda de configuración es ligeramente diferente de la tienda de opciones. Es similar a la función de configuración de la API compuesta de Vue. Pasamos una función que define algunas propiedades y métodos receptivos, y devuelve una función con las propiedades y métodos que queremos exponer. objeto de método. El código de ejemplo es el siguiente:

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

  return {
    
     count, increment }
})

En la tienda de configuración:

  • ref() es el atributo de estado
  • computado () es captadores
  • función () es acciones

Código de muestra

El siguiente es un ejemplo para ilustrar completamente el uso de la gestión de estado de Pinia. Ahora se deben lograr los siguientes efectos: Se deben
completar dos funciones en la página. Una función es controlar el salto de diferentes páginas al monitorear el valor de isShow , y la barra de menú inferior La visualización y ocultación de botones; otra función es conectarse a la red a través de una función para obtener la lista de películas y mostrarla en la página de detalles

En la API opcional, el código de implementación es el siguiente:

  1. Código en 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. El código en movieStore.js debajo de la carpeta de la tienda
// 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. El código del archivo Menu.vue en la carpeta de componentes
<!-- 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. El código de MovieList.vue en la carpeta de componentes
<!-- 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. El código de MovieDetails.vue en la carpeta de vistas
<!-- 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>

El código anterior muestra cómo compartir y administrar el estado usando store, getter y action en Pinia. Entre ellos, movieStore define una tienda que contiene dos estados de isShow y películas, y una acción para modificar isShow y obtener la lista de películas. En el componente Menu.vue, usamos el enlace useStore para obtener el estado isShow de la tienda y controlar la visualización y ocultación del botón de la barra de menú inferior según su valor. En el componente MovieList.vue, usamos el enlace useStore para obtener el estado de las películas de la tienda y la acción fetchMovies() para obtener la lista de películas de la red. En el componente MovieDetails.vue, usamos el gancho useRoute para obtener la identificación del parámetro de enrutamiento de la página actual, usamos el gancho useStore para obtener el estado de las películas de la tienda y obtener la información detallada de la película actual de acuerdo con movieId y captador getMovies().

Tenga en cuenta que en el gancho setup(), usamos el gancho useStore para obtener el estado y realizar operaciones desde la tienda. Dado que el enlace useStore devuelve un proxy reactivo, no necesitamos actualizar manualmente el estado de forma reactiva. Además, podemos desacoplar los componentes de la tienda, haciéndolos más fáciles de probar y reutilizar.

En la API combinada, el código de implementación es ligeramente diferente. Aquí solo tomamos la página MovieList.vue como ejemplo. Otras páginas están escritas de manera similar y no se mostrarán. El código de la página MovieList.vue es el siguiente :

<!-- 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>

Bien, este es el final de la introducción sobre el uso de Pinia para la gestión global del estado en Vue3. Si te gusta, dale me gusta y síguelo a favoritos.

Supongo que te gusta

Origin blog.csdn.net/w137160164/article/details/131160122
Recomendado
Clasificación