pinia 的 getters 是响应式、缓存化的状态加工层,支持函数式、this 式及带参写法;需避免异步、非响应式依赖和返回新引用以保缓存有效,并应拆分逻辑、收口至组件外提升复用与性能。

Pinia 的 Getters 就是状态的“智能加工车间”——它不改动原始 state,却能实时、响应式地输出你真正需要的数据,并且自动记住结果,只在必要时重算。
用对形式:函数式 vs this 式
Getter 的写法决定它能做什么:
- 用 (state) => ... 形式:适合简单计算,比如
fullName: (state) => `${state.firstName} ${state.lastName}`,不依赖其他 getter,轻量直接 - 用 getterName() { return this.xxx } 形式:当你需要复用另一个 getter,比如先过滤再计数:
activeItems() { return this.items.filter(i => i.active) }和activeCount() { return this.activeItems.length },后者靠 this 调用前者,天然复用缓存
带参数的 Getter:灵活但需留意缓存
要支持动态筛选(如按状态、关键词),Getter 必须返回函数:
- 写法示例:
tasksByStatus: (state) => (status) => state.tasks.filter(t => t.status === status) - 调用方式:
store.tasksByStatus('done')或解构后tasksByStatus('pending') - 注意:Pinia 默认不会为不同参数值分别缓存结果。如果高频调用且参数组合多,建议搭配
lodash.memoize或自行封装缓存逻辑,避免重复遍历
缓存不是万能的:避开性能陷阱
Getters 的缓存机制很聪明,但前提是它“认得出变化”。以下情况会破坏缓存效益:
- 在 getter 内部执行异步操作、发起 API 请求或读取非响应式外部变量(如 Date.now()、Math.random())
- 直接返回新对象或数组(如
() => ({ ...state.obj })),每次返回都是新引用,导致组件误判为变更而强制更新 - 把复杂逻辑堆在一个 getter 里。应拆成多个小 getter,让 Pinia 分别缓存中间结果,比如先
filteredList,再listCount,最后hasItems
和组件联动:干净又高效
不要在模板里写 v-if="items.filter(...).length > 0" 这类表达式。把逻辑收口到 getter,组件只消费结果:
- Store 中定义:
hasActiveTasks: (state) => state.tasks.some(t => t.active) - 组件中用
storeToRefs解构:const { hasActiveTasks } = storeToRefs(store) - 模板里直接写:
<div v-if="hasActiveTasks">有进行中的任务</div>,语义清晰,复用方便,还享受缓存










