Vue3的Pinia详解
Pinia 是由 Vue 官方团队开发的轻量级状态管理库,旨在为 Vue 应用提供更简洁、模块化的状态管理方案。
`Store`是一个保存:''状态''、''业务逻辑'' 的实体,每个组件都可以''读取''、''写入''它。 它有三个概念:`state`、`getter`、`action`,相当于组件中的: `data`、 `computed` 和 `methods`。
创建pinia
在src文件夹下创建store文件,及store文件里的具体文件名.ts文件
import { defineStore } from 'pinia'//创建一个求和的pinia,count可随意
export const useCountStore = defineStore('count',{//真正存储数据的地方,state需要以函数的形式返回state(){return{sum:6}}
})存储读取pinia
<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>
let sum = reactive({a:1,b:3,c:ref(4)
})sum.c.value //undefind
sum.c // 4let count = ref(4)count.value //4修改Pinia数据
<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
import { defineStore } from 'pinia'export const useCountStore = defineStore('count',{//actions里面放置的是一个一个的方法,用于响应组件中的动作actions:{increment(value){ //value为传递的数据//this.sum 访问state的值 this指的是 当前的store,也就是 CountStorethis.sum += value}},state(){return{sum:6}}
})storeToRefs
优雅获取处理store数据
<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' //引入storeToRefslet countStore = useCountStore()let { sum,xx } = storeToRefs(countStore)//如果使用 toRefs 的话,会获取countStore的所有东西,代价太大//而storeToRefs 只会关注store中的数据,不会对方法进行ref包裹</script>getters的使用
当`state`中的数据,需要经过处理后再使用时,可以使用`getters`配置
配置getters
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
<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' //引入storeToRefslet countStore = useCountStore()let { sum,xx,bigSum } = storeToRefs(countStore)</script>$subscribe的使用
通过 store 的 $subscribe() 方法侦听 state 及其变化
<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组合式写法
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 }
})