- Pinia 是 Vue.js 的一个状态管理库,用于在 Vue 应用程序中管理共享状态。它是 Vuex 的后继者,提供了一个简单、直观且灵活的方式来处理应用中的全局状态,比如用户登录信息、应用配置、购物车数据等。
- 与 Vuex 相比,Pinia 有更简洁的 API 和更好的类型支持(在 Type - Script 项目中),使得开发者能够更高效地管理应用状态
Pinia基本使用
Store
是一个保存:状态、业务逻辑的实体,每个组件都可以读取、写入它它有三个概念:
state
、getter
、action
,相当于组件中的:data
、computed
和methods
-
安装pinia
shellnpm i pinia
-
使用pinia
ts// main.ts // 引入createPinia import {createPinia} from "pinia"; const app = createApp(App) app.use(router) // 创建pinia const pinia = createPinia() // 使用pinia,在app挂载之前 app.use(pinia) app.mount('#app')
-
存储数据,创建store文件夹,存放store相关代码(和vuex一样)
State:用于数据的存储(对象类型数据),是store中唯一数据源
ts// 引入defineStore import {defineStore} from "pinia"; // 官方推荐命名与hooks一样,use开头 // 第一个参数可以理解为给Store命名,这个名称在整个应用程序的 Pinia 实例中必须是唯一的,它就像是一个标识符,用来区分不同的 Store // 第一个参数可以写成和文件名字一样 // 第二个参数是一个配置对象 export const useStatusStore = defineStore("status", { // 存储数据的地方-Pinia唯一的数据源 // state必须是一个函数,且返回一个对象 state() { // 定义一个flag和isShow return {flag:0,isShow:true} }, })
-
读取数据
ts// 引入useStatusStore import {useStatusStore} from "@/store/status"; // statusStore是一个reactive响应式对象 const statusStore = useStatusStore() // 读取flag // statusStore是reactive响应式对象,但是里面的属性是ref的响应式对象 // 虽然是ref响应式对象,但是读取不需要.value,只有我们手动ref(xx)创建数据的时候需要.value console.log(statusStore.flag) // 通过$state读取,$state是一个特殊的属性, // 它代表了整个 store(仓库)的状态对象。这个状态对象包含了所有在state函数中定义的状态属性 // 也可以这样读取 console.log(statusStore.$state.flag)
pinia修改数据
-
直接修改
ts// 直接修改即可,不需要像vuex一样提交方法 statusStore.flag = 1
-
使用$patch方法
$patch
可以在一次操作中完成多个状态属性的更新,减少了多次触发状态更新机制的开销,提高效率ts//patch用于批量更新 store中的状态 //参数是一个对象,要修改的数据名-要改的值,支持批量修改 statusStore.$patch({ // flag改成1 isShow改成false flag: 1, isShow:false })
-
actions修改
使用actions需要先在Store里面配置actions
tsexport const useStatusStore = defineStore("status", { // state必须是一个函数,且返回一个对象 state() { return {flag: 0, isShow: true} }, // actions是一个对象,里面放置的是一个一个的动作方法,用于响应组件中的动作 actions:{ // 修改flag setFlag(value:number){ // 可以对数据进行一些其他逻辑处理 this.flag = value } } })
然后在组件中直接调用方法进行修改
tsconst statusStore = useStatusStore() statusStore.setFlag(1)
storeToRefs读取数据
- 借助
storeToRefs
将store
中的数据转为ref
对象,方便在模板中使用。pinia
提供的storeToRefs
只会将数据做转换,而Vue
的toRefs
会转换store
中所有
ts
// 引入
import {storeToRefs} from "pinia";
// let {flag,isShow} = statusStore 如果直接解构拿取数据,会丢失响应式
// 使用toRefs解构,可以实现解构并且响应式,但是是将数据、方法都转换了,不管有没有用
// let {flag,isShow} = toRefs(statusStore)
// 使用storeToRefs解构,只会关注Store里面的数据,不关注方法
let {flag, isShow} = storeToRefs(statusStore)
getters
当
state
中的数据,需要经过处理后再使用时,可以使用getters
配置
-
在Store里面写getters配置
tsexport const useStatusStore = defineStore("status", { state() { return {flag: 0, isShow: true} }, actions: { setFlag(value: number) { this.flag = value } }, // getters是一个配置对象,类似计算属性 getters: { // doubleFlag属性,值是flag的双倍 doubleFlag(): number { return this.flag * 2 }, // 箭头函数 doubleFlag1: state => state.flag * 2 } })
-
调用getters
tsstatusStore.doubleFlag statusStore.doubleFlag1
$subscribe
通过 store 的
$subscribe()
方法侦听state
及其变化
ts
const statusStore = useStatusStore()
// 类似于监视属性,当Store里的数据发生变化的时候触发,接受一个回调函数
statusStore.$subscribe((mutate, state) => {
// mutate:包含有关状态变化详细信息的对象
// state:一个只读的对象,表示 store 在状态变化后的最新状态
console.log(mutate,state)
})
Pinia组合式写法
ts
import {defineStore} from "pinia";
import {reactive} from "vue";
// 组合式写法,第二个参数不是对象了,是一个回调函数
export const useStatusStore = defineStore("status", () => {
// 在Store里面定义响应式数据,相当于在state里面定义了userList,userList就是state
const userList = reactive({id: "001", name: "001", age: 11})
// 相当于在getters里面定义doubleAge,调用需要以方法的形式调用,需要加括号
function doubleAge() {
return userList.age * 2
}
// 相当于在actions里面定义getUser,调用需要以方法的形式调用,需要加括号
function getUser() {
return userList
}
// 将数据暴露出去
return {userList,doubleAge,getUser}
})