Notas de uso do Pinia

Introdução

Pinia é uma nova biblioteca de gerenciamento de estado Vue desenvolvida pelos membros da equipe Vue.js.

Comparado com vuex

  1. O módulo do Pinia é mais parecido com ganchos, nenhum aninhamento é necessário, os módulos podem se referir uns aos outros, tornando a organização do código mais flexível
  2. Ele está em conformidade com o estilo da API de composição do Vue3 e pode ser combinado diretamente com a API do Vue3 para definir o estado
  3. Não há mutações, apenas estado, getters, ações e ferramentas de desenvolvimento também podem rastrear alterações de estado
  4. Ambos vue2 e vue3 podem suportar
  5. Inferência de tipo TypeScript

Instalar

yarn add pinia
# 或者使用 npm
npm install pinia
复制代码

exemplo completo

Primeiro você precisa introduzir em main.ts

import { createApp } from 'vue'
import { createPinia } from 'pinia'
​
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
复制代码

definir estado

A função defineStore é usada para definir um estado e retornar uma função que usa o estado.

Definimos o estado no arquivo /src/store/index.ts, é claro, ele também pode ser definido em outros arquivos, e defineStore pode definir várias coleções de estado

import { defineStore } from 'pinia'
​
// useStore 可以是 useUser、useCart 之类的任何东西
export const useCountStore = defineStore('count', {
    // state:定义状态
    state: ()=>({
        count: 0
    }),
    // getters:与vuex一致,类似于computer
    getters: {
        dbCount:(state)=>state.count*2
    },
    // actions:与vuex一致,用于修改状态
    actions: {
        countPlus() {
            this.count++
        }
        
    }
})
复制代码

O primeiro parâmetro de defineStore é o id único da loja na aplicação, e o segundo parâmetro é um objeto de opções, similar ao Vuex mas sem o campo Mutation

estado de uso

Chame o método useStore para retornar a instância da loja

<template>
  <div class='home'>
    <div>{
   
   {countStore.count}}</div>
    <button @click="countPlus">count++</button>
  </div>
</template>
​
<script setup lang="ts">
import {useCountStore} from "./useStore";
​
const countStore = useCountStore()
// 通过countStore可以直接访问到state、getters、actions中定义的状态和方法
countStore.count
countStore.dbCount
countStore.countPlus()
​
​
function countPlus(){
  // 可以直接修改 count
  countStore.count++
  // 也可以通过$state替换整个状态
  countStore.$state = {count: countStore.count+1}
  // 使用$patch修改状态
  countStore.$patch({
    count: countStore.count+1
  })
  // 调用actions中的方法
  countStore.countPlus()
}
​
</script>
复制代码

defineStore

Definir estado usando configuração

Estado

definir estado

export const useCountStore = defineStore('count', {
    state: ()=>({
        count: 0
    })
})
复制代码

acessar/modificar estado

const countStore = useCountStore()
// 访问
countStore.count
countStore.$state.count
​
// 可以直接修改 count
countStore.count++
// 也可以通过$state替换整个状态
countStore.$state = {count: countStore.count+1}
// 使用$patch修改状态
countStore.$patch({
  count: countStore.count+1
})
复制代码

Getters

Assim como nas propriedades calculadas, você pode combinar vários getters. thisAcesse quaisquer outros getters via .

export const useCountStore = defineStore('count', {
    state: ()=>({
        count: 0
    }),
    getters: {
        // 回调函数的参数为state
        dbCount:(state)=>state.count*2,
        // this为该store实例,可以访问到其他的getters
        doubleCountPlusOne() {
          return this.doubleCount + 1
        }
    }
})
复制代码

getter pass parâmetro

export const useCountStore = defineStore('count', {
    state: ()=>({
        count: 0
    }),
    getters: {
        // getters返回一个函数,并接受一个参数
        countFormat: (state) => {
          return (fmt) => state.count+fmt
        },
    }
})
复制代码

Getters de acesso para outras lojas

export const useUserStore = defineStore('user', {
    state: ()=>({
        name: 'yxx'
    }),
    getters: {
        countFormat: (state) => {
          return (fmt) => state.count+fmt
        },
    }
})
​
export const useCountStore = defineStore('count', {
    state: ()=>({
        count: 0
    }),
    getters: {
        // getters返回一个函数,并接受一个参数
        userCount: (state) => {
          const userStore = useUserStore()
          return `${userStore.name}写了${state.count}个bug`
        },
    }
})
复制代码

getters de acesso

const countStore = useCountStore()
​
countStore.dbCount
countStore.doubleCountPlusOne
countStore.countFormat('个')
countStore.userCount
​
复制代码

Ações

Ações são equivalentes a métodos em componentes. pode ser definido usando o atributo defineStore()emactions

export const useCountStore = defineStore('count', {
    state: ()=>({
        count: 0
    }),
    actions: {
      // 与getters一样,可以通过this访问该store实例
      countPlus() {
        this.count++
      },
      // actions 可以是异步的
      async asyncCountPlus(){
        const res = await axios.get('xxxx')
        this.count = res.data
      }
        
    }
})
复制代码

Ações para acessar outras Lojas

export const useUserStore = defineStore('user', {
    state: ()=>({
        name: 'yxx'
    }),
    actions: {
        setName: () => {
          this.name = 'yxx'
        },
    }
})
​
export const useCountStore = defineStore('count', {
    state: ()=>({
        count: 0
    }),
    actions: {
        setUserName: (state) => {
          const userStore = useUserStore()
          userStore.setName()
        },
    }
})
复制代码

ações de acesso

const countStore = useCountStore()
​
countStore.countPlus()
countStore.asyncCountPlus()
countStore.setUserName()
复制代码

Definir o estado usando a sintaxe da API de composição

O segundo parâmetro de defineStore também pode receber uma função, que pode retornar uma variável reativa e suas propriedades computadas, métodos de modificação, etc.

import {defineStore} from "pinia";
import {ref, computed} from "vue";
​
export const useCountStore = defineStore('count', ()=>{
    const count = ref(0)
    const dbCount = computed(()=>count.value*2)
    const userInfo = reactive({
        name: 'yxx',
        age: 12
    })
    function countPlus(){
        count.value++
    }
​
    return {count, dbCount, userInfo, countPlus}
})
复制代码

Este método não é diferente da instância retornada pelo primeiro estado de definição de método, e a maneira de acessar propriedades e métodos não mudou

Variáveis ​​reativas definidas usando ref ou reativa são equivalentes ao estado no estado

Propriedades calculadas definidas usando computado são equivalentes àquelas em getters

Outros métodos de return são equivalentes aos métodos em ações

<template>
  <div class="">
    <div>count: {
   
   {countStore.count}}</div>
    <div>dbCount: {
   
   {countStore.dbCount}}</div>
    <button @click="butClick">count++</button>
  </div>
</template>
​
<script setup lang="ts">
import {useCountStore} from "./useStore";
​
const countStore = useCountStore()
// 访问状态
countStore.count
// 或者
countStore.$state.count
// 访问计算属性  
countStore.dbCount
​
function butClick(){
  // 访问方法
  countStore.countPlus()
}
</script>
复制代码

armazenar atributos/métodos da instância

Os estados e métodos definidos em estado, getters e ações podem ser acessados ​​diretamente pela instância da loja. Além desses, existem os seguintes atributos/métodos

  • $id define o id do estado
  • $estado todos os estados
  • $patch modificar estado
  • $redefinir estado de redefinição
  • $subscribe status da assinatura
  • Ação $onActionInscrever-se

$ id

$id é o ID da instância da loja, que é o primeiro parâmetro de defineStore

const countStore = useCountStore()
countStore.id // => 'count'
复制代码

$estado

Use $state para acessar todos os estados e você pode substituir diretamente o estado inteiro

const countStore = useCountStore()
countStore.$state = {count: countStore.count+1}
复制代码

$patch

$patch é usado para modificar o estado, você pode passar um objeto diretamente ou pode passar uma função de retorno de chamada

const countStore = useCountStore()
​
// 传递对象
countStore.$patch({
  count: countStore.count+1
})
// 传递函数,函数第一个参数为state
countStore.$patch(state=>{
  state.count++
})
复制代码

$reiniciar

$reset é usado para redefinir o estado, todos os estados serão redefinidos para o valor inicial ao chamá-lo

const countStore = useCountStore()
​
countStore.$reset()
复制代码

$subscrever

$subscribe status da assinatura

O primeiro parâmetro aceita uma função callback que será chamada quando o estado for modificado

O segundo parâmetro aceita um objeto { destacado: verdadeiro }, destacado é falso por padrão e, quando definido como verdadeiro, a assinatura não será cancelada quando o componente for destruído

const countStore = useCountStore()
​
countStore.$subscribe((mutation, state) => {
  console.log('mutation',mutation)
  // 修改数据的方式
  // 'direct': 通过countStore.count直接修改
  // 'patch object' 使用countStore.$patch({})修改的数据
  // 'patch function' 使用countStore.$patch((state)=>void)修改的数据
  mutation.type
  // 与 cartStore.$id 相同
  mutation.storeId // 'cart'
  // 仅适用于 mutation.type === 'patch object'
  mutation.payload // 传递给$patch的对象
},{ detached: true })
复制代码

$onAction

$onAction se inscreve em uma Action e aceita uma função de retorno de chamada que será chamada quando a Action for chamada

const countStore = useCountStore()
​
countStore.$onAction(
    ({
      name, // action 的名字
      store, // store 实例
      args, // 调用这个 action 的参数
      after, // 在这个 action 执行完毕之后,执行这个函数
      onError, // 在这个 action 抛出异常的时候,执行这个函数
    })=>{
      console.log(name,store,args,after,onError)
      onError(()=>{
        console.log('action 抛出异常')
      })
})
复制代码

método de ferramenta

storeToRefs

Semelhante ao toRefs, usado para estruturar um objeto responsivo,

storeé um reactiveobjeto envolvido por um , o que significa que não precisa ser escrito após o getter .value, mas, como setupem props, não podemos desestruturar :

const countStore = useCountStore()
// 这不起作用,因为它会破坏响应式
// 这和从 props 解构是一样的
const { count, dbCount } = countStore
复制代码

Para extrair as propriedades da Store e mantê-la responsiva, você precisa usar storeToRefs(). Ele criará referências para quaisquer propriedades reativas. Isso é útil quando você apenas usa o estado na loja, mas não chama nenhuma ação:

const countStore = useCountStore()

const { count, dbCount } = storeToRefs(countStore)
// (试了一下,用toRefs也能实现同样的效果)
const { count, dbCount } = toRefs(countStore)


Link: https://juejin.cn/post/7146009047311843342

Acho que você gosta

Origin blog.csdn.net/m0_71231013/article/details/127090725
Recomendado
Clasificación