Pinia核心概念:Actions详解与应用指南
2025-07-06 02:25:20作者:丁柯新Fawn
什么是Actions
在Pinia状态管理库中,Actions相当于组件中的methods,用于封装业务逻辑。与Vue组件中的methods类似,Actions允许你定义各种操作来修改状态(state),但提供了更强大的功能和更灵活的用法。
基本用法
在defineStore()中使用actions属性定义Actions:
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++
},
randomizeCounter() {
this.count = Math.round(100 * Math.random())
},
},
})
注意:
- 不要使用箭头函数定义Actions,因为需要访问this
- this指向整个store实例,可以访问state、getters和其他actions
- 支持完整的类型推断和自动补全
异步Actions
Actions的一个重要特性是支持异步操作,你可以在其中使用await:
export const useUsers = defineStore('users', {
state: () => ({
userData: null,
}),
actions: {
async registerUser(login, password) {
try {
this.userData = await api.post({ login, password })
showTooltip(`Welcome back ${this.userData.name}!`)
} catch (error) {
showTooltip(error)
return error
}
},
},
})
异步Actions的典型使用场景包括:
- API调用
- 复杂业务逻辑处理
- 多个状态变更的组合操作
调用Actions
Actions可以像普通方法一样被调用:
<script setup>
const store = useCounterStore()
// 调用action
store.randomizeCounter()
</script>
<template>
<button @click="store.randomizeCounter()">随机化计数器</button>
</template>
跨Store访问
在Actions中可以方便地访问其他store:
import { useAuthStore } from './auth-store'
export const useSettingsStore = defineStore('settings', {
actions: {
async fetchUserPreferences() {
const auth = useAuthStore()
if (auth.isAuthenticated) {
this.preferences = await fetchPreferences()
} else {
throw new Error('用户必须认证')
}
},
},
})
与Options API配合使用
使用setup()方式
<script>
import { useCounterStore } from '../stores/counter'
export default defineComponent({
setup() {
const counterStore = useCounterStore()
return { counterStore }
},
methods: {
incrementAndPrint() {
this.counterStore.increment()
console.log('新计数:', this.counterStore.count)
},
},
})
</script>
使用mapActions辅助函数
import { mapActions } from 'pinia'
import { useCounterStore } from '../stores/counter'
export default {
methods: {
// 映射为this.increment()
...mapActions(useCounterStore, ['increment']),
// 自定义方法名
...mapActions(useCounterStore, { myOwnName: 'increment' }),
},
}
监听Actions
Pinia提供了$onAction方法来监听actions的执行:
const unsubscribe = store.$onAction(
({
name, // action名称
store, // store实例
args, // 传入的参数数组
after, // action成功后的钩子
onError, // action失败时的钩子
}) => {
const startTime = Date.now()
console.log(`开始执行 "${name}",参数: [${args.join(', ')}]`)
after((result) => {
console.log(
`"${name}" 执行完成,耗时 ${Date.now() - startTime}ms。结果: ${result}`
)
})
onError((error) => {
console.warn(
`"${name}" 执行失败,耗时 ${Date.now() - startTime}ms。错误: ${error}`
)
})
}
)
// 手动取消监听
unsubscribe()
默认情况下,action订阅会绑定到添加它们的组件上(如果store在组件的setup()中)。如果要在组件卸载后保持订阅,可以传递true作为第二个参数:
<script setup>
const someStore = useSomeStore()
// 组件卸载后仍保持订阅
someStore.$onAction(callback, true)
</script>
最佳实践
- 业务逻辑封装:将复杂的业务逻辑封装在actions中,保持组件的简洁性
- 错误处理:在异步actions中妥善处理错误,提供友好的错误提示
- 组合使用:一个action可以调用其他action,实现逻辑复用
- 适度拆分:避免编写过于庞大的action,保持单一职责原则
- 监听机制:合理使用$onAction进行调试和监控
通过合理使用Pinia的Actions,你可以构建出结构清晰、易于维护的状态管理代码,为应用开发带来极大的便利。