4.1 Getters 核心概念
- Getter
- 基于 state(或其它 getter)计算出的派生值,等价于 store 层的
computed。 - 缓存(Caching)
- getter 结果会被缓存,只有依赖的响应式数据变化时才重新计算,多次访问不重复计算。
- state 参数
- 选项式 getter 的第一个参数是 state,用箭头函数可自动推断类型。
- this 上下文
- 用普通函数写 getter 时,
this指向整个 store,可访问其它 getter/action。 - 带参 getter
- 返回一个函数的 getter,可接收参数(如按 id 查找),但这种 getter 不缓存。
- 组合式 getter
- 组合式 store 中用
computed(() => ...)定义 getter,并 return 出来。
4.2 基础 Getter
export const useCartStore = defineStore("cart", {
state: () => ({
items: [] as { name: string; price: number; qty: number }[],
}),
getters: {
// 箭头函数 + state 参数,自动推断返回类型
itemCount: (state) => state.items.reduce((n, i) => n + i.qty, 0),
totalPrice: (state) =>
state.items.reduce((sum, i) => sum + i.price * i.qty, 0),
},
});
4.3 访问其它 Getter
getter 之间可以互相引用。若要引用其它 getter,需用普通函数并通过 this 访问(此时应显式标注返回类型,帮助 TS 推断):
getters: {
totalPrice: (state) =>
state.items.reduce((s, i) => s + i.price * i.qty, 0),
// 引用 totalPrice,需用普通函数拿 this,标注返回类型
totalWithTax(): number {
return Math.round(this.totalPrice * 1.13);
},
},
箭头函数拿不到 this
箭头 getter 只能通过参数 state 访问状态,拿不到 this。需要引用其它 getter 时改用普通函数并标注返回类型。
4.4 带参数的 Getter
让 getter 返回一个函数,就能接收参数(比如按 id 查商品):
getters: {
// 返回函数 → 可传参
getItemById: (state) => {
return (id: number) =>
state.items.find((i) => i.id === id);
},
},
// 组件中调用
const cart = useCartStore();
const item = cart.getItemById(42);
带参 getter 不缓存
返回函数的 getter 每次调用都会执行,失去缓存优势。如果结果昂贵且参数固定,考虑在组件里用 computed 缓存,或改造数据结构(如把数组转成 Map)。
4.5 缓存机制详解
Getter 的缓存和 Vue computed 完全一致:
- 首次访问时计算并缓存结果。
- 只要依赖的响应式数据没变,后续访问直接返回缓存,不重新计算。
- 依赖变化时,缓存失效,下次访问才重新计算(惰性求值)。
| 场景 | 是否重新计算 |
|---|---|
| 依赖的 state 未变,多次读取 | 否(返回缓存) |
| 依赖的 state 变化后再读取 | 是 |
| 带参 getter(返回函数) | 每次调用都执行 |
| getter 内引用了非响应式的外部变量 | 不会因它变化而更新(易踩坑) |
4.6 组合式写法的 Getter
import { defineStore } from "pinia";
import { ref, computed } from "vue";
export const useCartStore = defineStore("cart", () => {
const items = ref<Item[]>([]);
// computed 即 getter,自动缓存
const totalPrice = computed(() =>
items.value.reduce((s, i) => s + i.price * i.qty, 0)
);
// 带参 getter:computed 返回函数
const getItemById = computed(() => {
return (id: number) => items.value.find((i) => i.id === id);
});
return { items, totalPrice, getItemById };
});
4.7 在模板中使用
<script setup lang="ts">
import { storeToRefs } from "pinia";
import { useCartStore } from "@/stores/cart";
const cart = useCartStore();
const { totalPrice, itemCount } = storeToRefs(cart);
</script>
<template>
<p>共 {{ itemCount }} 件,合计 ¥{{ totalPrice }}</p>
</template>
4.8 小结与下一步
- Getter = store 的
computed,自动缓存、惰性求值。 - 箭头函数用
state参数;引用其它 getter 用普通函数 +this+ 返回类型标注。 - 带参 getter 靠"返回函数"实现,但不缓存。
- 下一章深入 Actions——同步/异步动作、组合 store、错误处理。