pinia是什么?
如果你学过Vue2,那么你一定使用过Vuex。我们都知道Vuex在Vue2中主要充当状态管理的角色,所谓状态管理,简单来说就是一个存储数据的地方,存放在Vuex中的数据在各个组件中都能访问到,它是Vue生态中重要的组成部分。
既然Vuex那么重要,那么在Vue3中岂能丢弃!
在Vue3中,可以使用传统的Vuex来实现状态管理,也可以使用最新的pinia来实现状态管理,我们来看看官网如何解释pinia的。
官网解释:
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。
从上面官网的解释不难看出,pinia和Vuex的作用是一样的,它也充当的是一个存储数据的作用,存储在pinia的数据允许我们在各个组件中使用。
实际上,pinia就是Vuex的升级版,官网也说过,为了尊重原作者,所以取名pinia,而没有取名Vuex,所以大家可以直接将pinia比作为Vue3的Vuex。
搭建 pinia 环境
第一步:npm install pinia
第二步:如下操作src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
/* 引入createPinia,用于创建pinia */
import { createPinia } from 'pinia'
/* 创建pinia */
const pinia = createPinia()
const app = createApp(App)
/* 使用插件 */{}
app.use(pinia)
app.mount('#app')
存储+读取数据
-
Store
是一个保存:状态、业务逻辑 的实体,每个组件都可以读取、写入它。 -
它有三个概念:
state
、getter
、action
,相当于组件中的:data
、computed
和methods
。 -
具体编码:
src/store/count.ts
// 引入defineStore用于创建store
import {defineStore} from 'pinia'
// 定义并暴露一个store
export const useCountStore = defineStore('count',{
// 动作
actions:{},
// 状态
state(){
return {
sum:6
}
},
// 计算
getters:{}
})
4. 组件中使用state
中的数据
<template>
<h2>当前求和为:{{ countStore.sum }}</h2>
</template>
<script setup lang="ts" name="Count">
// 引入对应的countXxxxxStore
import {useCountStore} from '@/store/count'
// 调用useXxxxxStore得到对应的store
const countStore= useCountStore()
</script>
修改数据
第一种修改方式,直接修改
countStore.sum = 666
<template>
<h2>当前求和为:{{ sumStore.sum }}</h2>
<button @click="add">按钮</button>
</template>
<script setup lang="ts" name="Count">
// 引入对应的useXxxxxStore
import {useCountStore} from '@/store/count'
// 调用useXxxxxStore得到对应的store
const sumStore = useCountStore()
//store中对应的值+1
function add(){
sumStore.sum+=1
}
</script>
第二种修改方式:批量修改
通过$patch可以直接对整个数据体进行修改
sumStore.$patch({
sum:sumStore.sum+1
})
<template>
<h2>当前求和为:{{ sumStore.sum }}</h2>
<button @click="add">按钮</button>
</template>
<script setup lang="ts" name="Count">
// 引入对应的useXxxxxStore
import {useCountStore} from '@/store/count'
// 调用useXxxxxStore得到对应的store
const sumStore = useCountStore()
//store中对应的值+1
function add(){
sumStore.$patch({
sum:sumStore.sum+1
})
}
</script>
第三种修改方式:借助action
修改(action
中可以编写一些业务逻辑)
在对应的store的ts下进行修改
actions:{
add(value:number){
this.sum+=value
},
reduce(value:number){
this.sum-=value
}
}
然后再对应的组件中进行调用
sumStore.add(1)
完整代码
import {defineStore} from 'pinia'
export const useCountStore = defineStore('count',
{
//触发逻辑
actions:{
add(value:number){
this.sum+=value
},
reduce(value:number){
this.sum-=value
}
},
state() {
return{
sum:0
}
},
getters:{}
})
<template>
<h2>当前求和为:{{ sumStore.sum }}</h2>
<button @click="add">按钮</button>
</template>
<script setup lang="ts" name="Count">
// 引入对应的useXxxxxStore
import {useCountStore} from '@/store/count'
// 调用useXxxxxStore得到对应的store
const sumStore = useCountStore()
//store中对应的值+1
function add(){
sumStore.add(1)
}
</script>
storeToRefs
-
借助
storeToRefs
将store
中的数据转为ref
对象,方便在模板中使用。 -
注意:这里推荐使用storeToRefs的原因是
pinia
提供的storeToRefs
只会将数据做转换,而Vue
的toRefs
会转换store
中数据会带来很多不必要的开销。
<template>
<div class="count">
<h2>当前求和为:{{sum}}</h2>
</div>
</template>
<script setup lang="ts" name="Count">
import { useCountStore } from '@/store/count'
/* 引入storeToRefs */
import { storeToRefs } from 'pinia'
/* 得到countStore */
const countStore = useCountStore()
/* 使用storeToRefs转换countStore,随后解构 */
const {sum} = storeToRefs(countStore)
</script>
getters
-
概念:当
state
中的数据,需要经过处理后再使用时,可以使用getters
配置,类似于计数数据。 -
追加
getters
配置。
getters:{
//当前数值翻10倍
tenfoldSum:(state):void=>{
let newSum = state.sum * 10
state.sum=newSum
}
}
完整代码
import {defineStore} from 'pinia'
export const useCountStore = defineStore('count',
{
//触发逻辑
actions:{},
state() {
return{
sum:1
}
},
getters:{
//当前数值翻10倍
tenfoldSum:(state):void=>{
let newSum = state.sum * 10
state.sum=newSum
}
}
})
<template>
<h2>当前求和为:{{ sumStore.sum }}</h2>
<button @click="sumStore.tenfoldSum">按钮*10</button>
</template>
<script setup lang="ts" name="Count">
// 引入对应的useXxxxxStore
import {useCountStore} from '@/store/count'
// 调用useXxxxxStore得到对应的store
const sumStore = useCountStore()
</script>
$subscribe
它这个 API 的方法,根据名字它是 订阅 的意思,可知它的主要是用于监听 state 里面的值是否发生了变化。
它返回一个函数,这个函数里面有两个参数
-
第一个参数 args,这个 args 里面的东西,就是 vue3 中的 watchEffect 里面的东西
-
第二个参数 state,这个就是我们当前的 state
sumStore.$subscribe((m,s)=>{
console.log('???',m,s)
})
打印结果: