前端系列-8 集中式状态管理工具pinia
集中式状态管理工具—pinia
vue3中使用pinia作为集中式状态管理工具,替代vue2中的vuex。
pinia文档可参考: https://pinia.web3doc.top/introduction.html
1.项目集成pinia
安装pinia依赖:
npm install pinia
在main.ts中引入pinia
import { createApp } from 'vue'
import App from './App.vue'
// 从pinia库引入createPinia方法
import { createPinia } from 'pinia'
//调用createPinia方法创建pinia对象,设置到APP中
createApp(App).use(createPinia()).mount('#app')
2.定义store
pina提供了defineStore方法创建store,store作为集中式状态管理的实体,可被任意组件读取/写入数据。定义的store一般放在src/stores目录下。
import {defineStore} from 'pinia'
// 定义并暴露一个store
export const useXXXStore = defineStore('XXX', {
// 配置信息
})
defineStore方法接收两个参数,store的唯一标识符和store的配置对象。其中,store配置对象中可以包含 state函数、actions对象、getters对象。
state中可以定义状态信息,getters基于state定义计算属性,actions中定义state相关的操作方法。以下结合案例进行说明:
// src/stores/clock.ts
import { defineStore } from 'pinia'
export const useClockStore = defineStore('clock', {
state: () => {
return {
hourHand: 0,
minuteHand: 0,
secondHand: 0
}
},
getters:{
time() {
return this.hourHand +"时: "+this.minuteHand +"分: "+this.secondHand +"秒";
}
},
actions: {
increHour() {
this.hourHand++;
},
getTime() {
return this.time;
}
},
})
state中包含3个状态属性:hourHand和minuteHand和secondHand,初始值和默认值为0;
getters中定义了一个获取时间的方法time():根据状态值计算出时间信息;
actions中定义了一个修改状态变量的方法和一个获取计算属性的方法。
3.使用store
在任意组件中,可以引入和使用章节2中定义的store,方式如下:
import { useClockStore } from '@/stores/clock'
const clockStore = useClockStore()
得到clockStore这个store后,可以直接在template或者script脚本中通过属性名获取state的属性(含计算属性):
clockStore.time
clockStore.hourHand
clockStore.minuteHand
clockStore.secondHand
也可以调用store在actions中定义的方法:
clockStore.increHour()
clockStore.getTime()
使用章节2中定义的clock.ts完整的案例组件如下所示:
<template>
<div>
<p>
<span>{{clockStore.hourHand}}</span>
<span>:</span>
<span>{{clockStore.minuteHand}}</span>
<span>:</span>
<span>{{clockStore.secondHand}}</span>
</p>
<button @click="addHour">addHourBtn</button>
<button @click="showTime">showTimeBtn</button>
</div>
</template>
<script lang="ts" setup>
import { useClockStore } from "@/stores/clock.ts";
const clockStore = useClockStore();
function addHour() {
clockStore.increHour();
}
function showTime() {
alert(clockStore.time);
}
</script>
此时,clockStore中的状态属性和计算属性作为响应式数据。
除了上述通过store中actions定义的方法外,还可通过以下方式直接修改状态值:
clockStore.hourHand=12
// 批量修改
clockStore.$patch({
hourHand:12,
minuteHand:30,
secondHand:0
})
4.响应式状态提取
章节3中提到过clockStore对象的状态属性和计算属性作为响应式数据,且可以直接操作clockStore对象的属性。
但是如果将其进行提取,则会失去响应式:
// clockStore.hourHand为响应式,修改为12后,页面会发生变化
clockStore.hourHand=12
// hour不是响应式对象
let hour = clockStore.hourHand
可以通过pinia的storeToRefs为其提供了一个解决方案:
import { storeToRefs } from 'pinia'
// 根据状态名称进行提取
const {hourHand, minuteHand,secondHand} = storeToRefs(clockStore)
hourHand.value = hourHand.value +100;
此时,可以在template结构中直接使用hourHand, minuteHand,secondHand,而不需要再使用clockStore.hourHand, clockStore.minuteHand,clockStore.secondHand.
解析出的数据为ObjectRefImpl类型,因此在script脚本中,修改和获取值时需要使用.value进行值的提取。
5.订阅store状态变化
可以通过store对象的$subscribe方法监听状态的变化,使用如下所示:
import { useClockStore } from "@/stores/clock.ts";
const clockStore = useClockStore();
clockStore.$subscribe((mutate, state)=>{
// 定制操作
console.log(mutate)
console.log(state)
})
mutate中包含了发生变化的属性key以及变化前后的值;state为更新后的状态对象。
mutate参数打印信息如下:
{storeId: "clockStore", type: "direct", events:{key: "hourHand", oldValue: 0, newValue: 1}}
state参数打印信息如下:
Proxy {hourHand: 1, minuteHand: 0, secondHand: 0}
原文地址:https://blog.csdn.net/Sheng_Q/article/details/140685989
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!