Pinia 사용 참고 사항

소개

Pinia는 Vue.js 팀원이 개발한 새로운 Vue 상태 관리 라이브러리입니다.

vuex와 비교

  1. Pinia의 모듈은 후크와 비슷하고 중첩이 필요하지 않으며 모듈이 서로를 참조할 수 있으므로 코드 구성이 더 유연해집니다.
  2. Vue3의 Composition api 스타일을 준수하며 Vue3의 API와 직접 결합하여 상태를 정의할 수 있습니다.
  3. 변형이 없으며 상태, getter, 작업 및 devtools만 상태 변경을 추적할 수 있습니다.
  4. vue2와 vue3 모두 지원 가능
  5. TypeScript 유형 추론

설치하다

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

완전한 예

먼저 main.ts에 소개해야 합니다.

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

상태 정의

defineStore 함수는 상태를 정의하고 상태를 사용하는 함수를 반환하는 데 사용됩니다.

우리는 /src/store/index.ts 파일에서 상태를 정의합니다. 물론 다른 파일에서도 정의할 수 있으며 defineStore는 여러 상태 컬렉션을 정의할 수 있습니다.

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++
        }
        
    }
})
复制代码

defineStore의 첫 번째 매개변수는 애플리케이션 내 상점의 고유 ID이고 두 번째 매개변수는 Vuex와 유사하지만 Mutation 필드가 없는 options 객체입니다.

사용현황

useStore 메서드를 호출하여 스토어 인스턴스를 반환합니다.

<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

구성을 사용하여 상태 정의

상태

상태 정의

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

액세스/수정 상태

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
})
复制代码

게터

계산된 속성과 마찬가지로 여러 게터를 결합할 수 있습니다. 를 통해 this다른 게터에 액세스합니다 .

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

getter 전달 매개변수

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

다른 상점에 대한 액세스 getter

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`
        },
    }
})
复制代码

액세스 게터

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

행위

작업은 구성 요소의 메서드와 동일합니다. defineStore()의 속성을 사용하여 actions정의 할 수 있습니다.

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
      }
        
    }
})
复制代码

다른 Store에 접근하기 위한 조치

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()
        },
    }
})
复制代码

액세스 작업

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

구성 API 구문을 사용하여 상태 정의

defineStore의 두 번째 매개변수는 반응 변수와 계산된 속성, 수정 방법 등을 반환할 수 있는 함수를 받을 수도 있습니다.

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}
})
复制代码

이 메서드는 첫 번째 메서드 정의 상태에서 반환한 인스턴스와 다르지 않으며 속성 및 메서드에 액세스하는 방법은 변경되지 않았습니다.

ref 또는 reactive를 사용하여 정의된 반응 변수는 state in state와 동일합니다.

computed를 사용하여 정의된 계산 속성은 getter의 속성과 동일합니다.

return의 다른 메서드는 action의 메서드와 동일합니다.

<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>
复制代码

인스턴스 속성/메소드 저장

state, getter, action에 정의된 상태와 메서드는 스토어 인스턴스에서 직접 접근할 수 있으며, 그 외에 다음과 같은 속성/메서드가 있습니다.

  • $id는 상태의 ID를 정의합니다.
  • $state 모든 상태
  • $patch 수정 상태
  • $reset 재설정 상태
  • $subscribe 구독 상태
  • $onAction구독 작업

$id

$id는 저장소 인스턴스의 ID이며 defineStore의 첫 번째 매개변수입니다.

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

$상태

$state를 사용하여 모든 상태에 액세스하고 전체 상태를 직접 교체할 수 있습니다.

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

$패치

$patch는 상태를 수정하는 데 사용되며 개체를 직접 전달하거나 콜백 함수를 전달할 수 있습니다.

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

$reset

$reset은 상태를 재설정하는 데 사용되며 모든 상태는 호출 시 초기 값으로 재설정됩니다.

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

$구독

$subscribe 구독 상태

첫 번째 매개변수는 상태가 수정될 때 호출될 콜백 함수를 허용합니다.

두 번째 매개변수는 { detached: true } 객체를 받아들이고 detached는 기본적으로 false이며 true로 설정하면 구성 요소가 파괴되어도 구독이 취소되지 않습니다.

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은 Action을 구독하고 Action이 호출될 때 호출될 콜백 함수를 수락합니다.

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 抛出异常')
      })
})
复制代码

도구 방법

storeToRefs

반응 객체를 구성하는 데 사용되는 toRefs와 유사하게,

store는 a 로 래핑된 객체 입니다 reactive. 즉 .value, getter 뒤에 작성할 필요는 없지만 setupin 과 같이 분해할 수 없습니다 .props

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

반응성을 유지하면서 Store에서 속성을 추출하려면 storeToRefs(). 반응 속성에 대한 참조를 생성합니다. 이것은 상점에서 상태를 사용하지만 어떤 조치도 호출하지 않을 때 유용합니다.

const countStore = useCountStore()

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


링크: https://juejin.cn/post/7146009047311843342

Guess you like

Origin blog.csdn.net/m0_71231013/article/details/127090725