pinia也是集中式管理状态容器,类似于vuex。但是核心概念没有mutation、modules,使用方式参照官网 pinia官网
pinia优点
- pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。
- pinia中action支持同步和异步,Vuex不支持
- 良好的Typescript支持,毕竟我们Vue3都推荐使用TS来编写,这个时候使用pinia就非常合适了
无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,稍显麻烦,而pinia中每个store都是独立的,互相不影响。 - 体积非常小,只有1KB左右。
- pinia支持插件来扩展自身功能。
- 支持服务端渲染。
在store下创建index.ts
import { createPinia } from 'pinia';
//createPinia方法可以用于创建大仓库
let store = createPinia();
//对外暴露,安装仓库
export default store;
创建info小仓库
import { defineStore } from "pinia";
//第一个仓库:小仓库名字 第二个参数:小仓库配置对象
//defineStore方法执行会返回一个函数,函数作用就是让组件可以获取到仓库数据
let useInfoStore = defineStore("info", {
//存储数据:state
state: () => {
return {
count: 99,
arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
actions: {
//注意:函数没有context上下文对象
//没有commit、没有mutations去修改数据
updateNum(a: number, b: number) {
this.count += a;
}
},
getters: {
total() {
let result:any = this.arr.reduce((prev: number, next: number) => {
return prev + next;
}, 0);
return result;
}
}
});
//对外暴露方法
export default useInfoStore;
在页面中使用仓库:
<template>
<div class="child">
<h1>{{ infoStore.count }}---{{infoStore.total}}</h1>
<button @click="updateCount">点击我修改仓库数据</button>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
console.log(infoStore);
//修改数据方法
const updateCount = () => {
//仓库调用自身的方法去修改仓库的数据
infoStore.updateNum(66,77);
};
</script>
Pinia 中关于 TypeScript 类型推断。Pinia 默认提供良好的 TypeScript 支持,但是要想获得完整的类型推断,需要遵循一些使用建议:
- 声明 state 建议使用箭头函数,会自动推断属性的类型。如果使用非箭头函数,在 getters 中使用形参 state访问属性TypeScript 无法识别
const useStore = defineStore('info', {
// 使用非箭头函数定义
state() {
return {
count: 0
}
},
getters: {
// 使用 state 访问状态
doubleCount(state) {
return state.count * 2;
}
},
actions: {}
})
- 声明 Getters 属性建议使用 state 参数访问状态(箭头函数或非箭头函数),非箭头函数虽然可以使用 this,但不会自动推断类型(当没有声明 state 形参,或 state 使用非箭头函数定义时)
const useStore = defineStore('info', {
state: () => ({ //为了避免使用 this,官方建议使用箭头函数
count: 0
}),
getters: {
doubleCount() {
return this.count * 2
},
// 解决办法1
doubleCount2(state) {
return this.count * 2
},
// 解决办法2
doubleCount3():number {
return this.count * 2
}
},
actions: {}
}
})
建议仅当需要获取整个 store 时使用 this,但必须显式的定义函数返回类型,TypeScript 不会自动推断
建议使用 this 的时候不要声明 state 形参