Pinia是一个全新的Vue状态管理库,由 Vue.js团队中成员所开发的,因此也被认为是下一代的 Vuex。同时是 vue 作者尤雨溪强势推荐的 vue3 状态管理工具,小伙伴们赶紧学起来吧。
一、安装
yarn add pinia
二、使用
首先我们需要在项目的 main.js 中使用创建并使用 pinia
import { createPinia } from 'pinia'
app.use(createPinia())
三、定义一个 Store
像 vuex 一样,我们需要在项目里定义一个 store 仓库
import { defineStore } from 'pinia'
// main 是应用程序中 store 的唯一 id
export default defineStore('main', {
state: () => {},
getters: {},
actions: {}
})
使用 store
<script setup>
// storeToRefs 可以让 state 里的属性保持响应式
import { storeToRefs } from 'pinia'
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
// 这里直接解构出来使用
const { count } = storeToRefs(mainStore)
</script>
<template>
<p>{{ count }}</p>
</template>
<style>
</style>
四、State
访问 state
默认情况下,可以通过 store 实例访问状态来直接读取和写入状态
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
// 通过 mainStore 直接可以访问里面的状态
console.log(mainStore.count)
</script>
重置状态
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
mainStore.$reset()
</script>
改变状态
直接修改
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
mainStore.count++
</script>
通过 $patch 对象 修改
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
mainStore.$patch({
count: mainStore.count + 1
})
</script>
通过 $patch 函数 修改
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
mainStore.$patch(state => {
state.count++
})
</script>
替代 state
您可以通过 $state 属性设置新对象来替换 Store 的整个状态
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
mainStore.$state = { a: 1, b: 2 }
</script>
也可以通过更改 pinia 实例的 state 来替换应用程序的整个状态。
import { createPinia } from 'pinia'
const pinia = createPinia()
// 替换整个应用程序的状态
pinia.state.value = {}
app.use(pinia)
订阅状态
在 pinia 中我们可以通过 $subscribe()来查看状态及其变化
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
mainStore.$subscribe((mutation, state) => {
// mutation 触发类型 ( 'direct' | 'patch object' | 'patch function' )
console.log(mutation);
// state 就是 store 的状态
console.log(state);
})
</script>
默认情况下,state subscriptions 绑定到添加它们的组件,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 { detached: true } 作为第二个参数传递给 detach 当前组件的 state subscription
Getters
getter 完全等同于 store 状态的计算值
定义 getters
export default defineStore('main', {
...,
getters: {
getCount: state => state.count + 10
}
})
访问 getters
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
console.log(mainStore.getCount)
</script>
Actions
actions 相当于组件中的methods
定义 actions
import { defineStore } from 'pinia'
export default defineStore('main', {
...,
actions: {
test() {
this.count++
}
}
})
使用 actions
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
// 调用 actions
mainStore.test()
</script>
订阅 actions
可以使用 $onAction()订阅 action 及其结果。after 处理 Promise 并允许您在 action 完成后执行函数。onError 允许您在处理中抛出错误。
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
const unsubscribe = mainStore.$onAction(
({
name, // action 的名字
store, // store 实例
args, // 调用这个 action 的参数
after, // 在这个 action 执行完毕之后,执行这个函数
onError, // 在这个 action 抛出异常的时候,执行这个函数
}) => {
// 如果 action 成功并且完全运行后,after 将触发。
// 它将等待任何返回的 promise
after((result) => {
})
// 如果 action 抛出或返回 Promise.reject ,onError 将触发
onError((error) => {
})
}
)
// 手动移除订阅
unsubscribe()
</script>
默认情况下,action subscriptions 绑定到添加它们的组件,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 true 作为第二个参数传递给当前组件的 detach action subscription
<script setup>
import useMainStore from '@/stores/index'
const mainStore = useMainStore()
// 此订阅将在组件卸载后保留
const unsubscribe = mainStore.$onAction(callback, true)
</script>