Vue3 -pinia 中的 getters 和 actions

刚学习 Pinia (或 Vuex) 的 store 的时候,发现 getters 和 actions 里都可以写方法,一时搞不懂两者有什么区别。但是事实上,虽然 Action 里也能写方法,但它和 Getter 的设计目的和工作方式完全不同。
本文只针对选项式写法的 store,对于组合式写法的 store 不存在这个问题,请见 pinia 的选项式和组合式写法
简单来说,Getter 是 “计算属性版的 State”。它的核心价值在于 派生状态 (Derived State) 和 结果缓存 (Caching)。
1. Getter 的核心价值
想象一下你在 Vue 组件里使用的 computed
计算属性,Getter 在 Pinia Store 里的角色和它几乎一模一样。
a. 派生状态 (Derived State)
你的 state
应该是最原始、最基础的数据。很多时候,我们在组件中需要的数据并不是原始数据本身,而是基于原始数据计算或处理过的数据。
举个例子:一个待办事项列表
- State:
todos: [{ id: 1, text: '学习 Pinia', done: true }, { id: 2, text: '吃饭', done: false }]
- 需求: 在页面 A 显示“已完成”的待办事项,在页面 B 显示“已完成”的数量。
如果没有 Getter:
你需要在页面 A 的组件里写一个计算属性来过滤 todos
数组:
const completedTodos = computed(() => store.todos.filter(todo => todo.done))
然后又需要在页面 B 的组件里写另一个计算属性来计算数量:
const completedCount = computed(() => store.todos.filter(todo => todo.done).length)
这里的问题是:
- 代码重复:过滤逻辑
filter(todo => todo.done)
在多处重复。 - 逻辑分散:处理 Store 数据的逻辑分散在各个组件中,而不是集中在 Store 里。
有了 Getter:
你可以在 Store 中定义 Getter:
1 | // stores/todo.js |
现在,在任何组件里,你都可以直接使用这些计算好的、可复用的派生状态:
1 | <template> |
代码变得非常干净、可维护,并且逻辑集中。
b. 结果缓存 (Caching)
这个特性尤其像是 computed,也是 Getter 最重要 的特性,是它和普通方法(比如 Action 里的方法)的根本区别。
- Getter 是响应式的,并且会缓存结果。一个 Getter 只有在它所依赖的
state
发生变化时,才会重新计算。如果依赖没变,无论你访问多少次这个 Getter,它都会立刻返回上一次计算好的结果,而不会重新执行计算函数。 - Action 里的方法不是。每次调用 Action 里的一个方法,这个方法内部的函数体都会被完整执行一遍。
再用上面的例子:
- 当你多次访问
todoStore.finishedTodosCount
时,只要todos
数组没有变化,过滤和计算长度的逻辑只会执行一次。后续的访问都是直接读取缓存,性能极高。 - 如果你在 Action 里写一个
getFinishedCount()
方法,每次调用它都会重新filter
和计算.length
,当todos
数组很大时,这会造成不必要的性能开销。
2. Getter vs. Action 的本质区别
特性 | Getters | Actions |
---|---|---|
核心目的 | 计算派生状态,像 Vue 的 computed 。 |
处理业务逻辑,特别是异步操作和修改 State,像 Vue 的 methods 。 |
🌟能否修改 State | 不能。Getters 是只读的,用于获取数据。 | 可以。Actions 的核心职责之一就是修改 State(例如 this.count++ )。 |
异步操作 | 不能。Getters 必须是同步函数。 | 可以。Actions 可以是 async/await 函数,常用于调用 API。 |
缓存 | 有。依赖的 State 不变,结果就不重新计算。 | 没有。每次调用都会重新执行。 |
调用方式 | 像属性一样访问:store.myGetter |
像方法一样调用:store.myAction() |
总结:什么时候用 Getter,什么时候用 Action?
-
当你需要根据现有的
state
计算出一些新值,并且这个值需要在多个地方使用时 -> 用Getter
。- 例子:购物车商品总价、筛选/排序后的列表、用户权限判断等。
- 口诀:“算”出来的状态,用 Getter。
-
当用户执行一个操作,需要修改
state
,或者需要执行一个异步任务(如从服务器获取数据)时 -> 用Action
。- 例子:用户点击按钮添加商品到购物车、登录时向服务器发送请求、从 API 获取用户列表并更新 State。
- 口诀:“做”某件事的动作,用 Action。
所以,Getter 并不是多余的,它和 Action 各司其职,共同构成了 Pinia 状态管理的最佳实践。Getter 负责“衍生数据”,Action 负责“业务动作”,两者完美互补,缺一不可。
- 标题: Vue3 -pinia 中的 getters 和 actions
- 作者: 三葉Leaves
- 创建于 : 2025-06-25 00:00:00
- 更新于 : 2025-07-10 13:40:50
- 链接: https://blog.oksanye.com/993c3f329f36/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。