소개
Pinia는 Vue.js 팀원이 개발한 새로운 Vue 상태 관리 라이브러리입니다.
vuex와 비교
- Pinia의 모듈은 후크와 비슷하고 중첩이 필요하지 않으며 모듈이 서로를 참조할 수 있으므로 코드 구성이 더 유연해집니다.
- Vue3의 Composition api 스타일을 준수하며 Vue3의 API와 직접 결합하여 상태를 정의할 수 있습니다.
- 변형이 없으며 상태, getter, 작업 및 devtools만 상태 변경을 추적할 수 있습니다.
- vue2와 vue3 모두 지원 가능
- 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 뒤에 작성할 필요는 없지만 setup
in 과 같이 분해할 수 없습니다 .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