Pinia 是由 Vue 官方团队开发的轻量级状态管理库,旨在为 Vue 应用提供更简洁、模块化的状态管理方案。
`Store`是一个保存:''状态''、''业务逻辑'' 的实体,每个组件都可以''读取''、''写入''它。 它有三个概念:`state`、`getter`、`action`,相当于组件中的: `data`、 `computed` 和 `methods`。
创建pinia
在src文件夹下创建store文件,及store文件里的具体文件名.ts文件
javascript
import { defineStore } from 'pinia'
//创建一个求和的pinia,count可随意
export const useCountStore = defineStore('count',{
//真正存储数据的地方,state需要以函数的形式返回
state(){
return{
sum:6
}
}
})
存储读取pinia
javascript
<template>
<div> {{countStore.sum}} </div>
<button>加</button>
<button>减</button>
</template>
<script setup lang="ts">
import { useCountStore } from '@/store/count' //引入写好的store数据
let countStore = useCountStore()
//此时的countStore中的sum是一个ref,你可能会就觉得使用countStore.sum.value就可以拿到值
//其实不然,这是一个坑,之后再说
console.log(countStore.sum)//拿取值
console.log(countStore.$state.sum)//拿取值
</script>
javascript
let sum = reactive({
a:1,
b:3,
c:ref(4)
})
sum.c.value //undefind
sum.c // 4
let count = ref(4)
count.value //4
修改Pinia数据
javascript
<template>
<div> {{countStore.sum}} </div>
<button @click="add">加</button>
<button>减</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useCountStore } from '@/store/count' //引入写好的store数据
let countStore = useCountStore()
function add(){
//第一种修改方式,直接更改,而且store里的数据也是同步更改的。
//不像Vue2需要action和mutation
countStore.sum +=1
//第二种修改方式 适用于批量更改,如果要更改的store的数据过多,一行一行更改不够优雅
//countStore.sum +=1;countStore.xx +=1;countStore.yy +=1;
countStore.$patch({
sum:2,
xx:3,
yy:4
})
//第三种方式 需要使用actions,要在配置store中,怎么配置稍后
let n = ref(2)
countStore.increment(n.value)
}
</script>
配置pinia的actions
javascript
import { defineStore } from 'pinia'
export const useCountStore = defineStore('count',{
//actions里面放置的是一个一个的方法,用于响应组件中的动作
actions:{
increment(value){ //value为传递的数据
//this.sum 访问state的值 this指的是 当前的store,也就是 CountStore
this.sum += value
}
},
state(){
return{
sum:6
}
}
})
storeToRefs
优雅获取处理store数据
javascript
<template>
//这样countStore.sum获取值不够优雅
//<div> {{countStore.sum}} </div>
//<div> {{countStore.xx}} </div>
<div> {{sum}} </div>
<div> {{xx}} </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useCountStore } from '@/store/count' //引入写好的store数据
import { storeToRefs } from 'pinia' //引入storeToRefs
let countStore = useCountStore()
let { sum,xx } = storeToRefs(countStore)
//如果使用 toRefs 的话,会获取countStore的所有东西,代价太大
//而storeToRefs 只会关注store中的数据,不会对方法进行ref包裹
</script>
getters的使用
当`state`中的数据,需要经过处理后再使用时,可以使用`getters`配置
配置getters
javascript
import { defineStore } from 'pinia'
//创建一个求和的pinia,count可随意
export const useCountStore = defineStore('count',{
//真正存储数据的地方,state需要以函数的形式返回
state(){
return{
sum:6
}
},
getters:{
bigSum(state){
return state.sum *10
},
//bigSum:state => state.sum *10
//bigSum():number{
//return state.sum *10
//}
}
})
使用getters
javascript
<template>
<div> {{sum}} 放大十倍是{{ bigSum }}</div>
<div> {{xx}} </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useCountStore } from '@/store/count' //引入写好的store数据
import { storeToRefs } from 'pinia' //引入storeToRefs
let countStore = useCountStore()
let { sum,xx,bigSum } = storeToRefs(countStore)
</script>
$subscribe的使用
通过 store 的 $subscribe() 方法侦听 state 及其变化
javascript
<template>
<div> {{countStore.sum}} </div>
<button @click="add">加</button>
<button>减</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useCountStore } from '@/store/count' //引入写好的store数据
let countStore = useCountStore()
countStore.$subscribe((mutate,state)=>{
//参数mutate,state类似于watch的参数
})
function add(){
countStore.sum +=1
}
</script>
store组合式写法
javascript
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useCountStore = defineStore('count',()=>{
let sum = ref(0)
increment(value){ //value为传递的数据
sum.value += value
}
return { sum,increment }
})