Pinia中Getters的完整使用指南Getters作为计算属性支持函数形式state参数和this形式访问其他getter。典型用法包括基础状态派生、返回函数传参、条件过滤等8种场景可通过直接调用、解构或计算属性组合使用。高级技巧涉及缓存优化、类型支持和链式调用需注意返回对象时的性能问题。根据场景选择合适形式简单派生用函数形式依赖其他getter用this形式动态参数需返回函数。Pinia 中 Getters 的使用方式Pinia 的 Getters 完全等同于 Store 状态中的计算属性可以通过多种方式定义和使用。一、基础定义方式定义方式语法适用场景函数形式getterName: (state) { return ... }简单派生状态不需要 this 上下文this 形式getterName(): { return this.xxx }需要访问其他 getter 时二、完整示例演示// stores/user.ts import { defineStore } from pinia export const useUserStore defineStore(user, { state: () ({ firstName: 张, lastName: 三丰, age: 25, todos: [ { id: 1, text: 学习Pinia, done: true }, { id: 2, text: 学习Vue3, done: false }, { id: 3, text: 写代码, done: false } ] }), getters: { // 1️⃣ 基础形式使用 state fullName: (state) ${state.firstName} ${state.lastName}, // 2️⃣ 访问其他 getter使用 this fullNameWithAge(): string { return ${this.fullName}年龄${this.age} }, // 3️⃣ 返回函数动态传参注意这会缓存结果 getUserById: (state) { return (userId: number) { return state.todos.find(todo todo.id userId) } }, // 4️⃣ 已完成事项 completedTodos: (state) state.todos.filter(todo todo.done), // 5️⃣ 未完成事项使用 this 访问其他 getter pendingTodos(): any[] { return this.todos.filter((todo: any) !todo.done) }, // 6️⃣ 统计信息返回对象 todosStats(): { total: number, completed: number, pending: number } { return { total: this.todos.length, completed: this.completedTodos.length, pending: this.pendingTodos.length } }, // 7️⃣ 条件判断 isAdult: (state) state.age 18, // 8️⃣ 结合其他 getter 的复杂计算 summary(): string { const stats this.todosStats return 总共${stats.total}个任务已完成${stats.completed}个剩余${stats.pending}个 } } })三、在组件中使用 Getters 的多种方式template div !-- 1️⃣ 直接使用最常见 -- p全名{{ userStore.fullName }}/p p详细信息{{ userStore.fullNameWithAge }}/p !-- 2️⃣ 传参调用返回函数的 getter -- pID为1的事项{{ userStore.getUserById(1)?.text }}/p !-- 3️⃣ 解构使用需要配合 storeToRefs -- p是否成年{{ isAdult }}/p p任务统计{{ todosStats }}/p p摘要{{ summary }}/p !-- 4️⃣ 在计算属性中使用 -- p格式化后的信息{{ formattedInfo }}/p /div /template script setup langts import { useUserStore } from /stores/user import { storeToRefs } from pinia import { computed } from vue const userStore useUserStore() // 方式1直接使用推荐 console.log(userStore.fullName) // 方式2解构使用必须用 storeToRefs 保持响应性 const { fullName, isAdult, todosStats, summary } storeToRefs(userStore) // 方式3传参调用返回函数的 getter const todo1 userStore.getUserById(1) // 方式4在组合式函数中使用 function useUserGreeting() { const greeting computed(() { return 你好${userStore.fullName}${userStore.isAdult ? 欢迎成年用户 : 你好年轻人} }) return { greeting } } const { greeting } useUserGreeting() // 方式5结合 Vue 的计算属性 const formattedInfo computed(() { const stats userStore.todosStats return 【${userStore.fullName}】完成进度${stats.completed}/${stats.total} }) /script四、高级用法技巧// stores/advanced.ts import { defineStore } from pinia export const useAdvancedStore defineStore(advanced, { state: () ({ items: [ { id: 1, price: 100, quantity: 2, discount: 0.1 }, { id: 2, price: 200, quantity: 1, discount: 0 }, { id: 3, price: 300, quantity: 3, discount: 0.2 } ], taxRate: 0.08 }), getters: { // 1️⃣ 缓存计算结果默认行为 subtotal: (state) { console.log(计算小计...) // 只有 items 变化时才重新计算 return state.items.reduce((sum, item) { return sum (item.price * item.quantity * (1 - item.discount)) }, 0) }, // 2️⃣ 带参数的 getter返回函数 // 注意这个不会缓存结果每次调用都重新计算 getItemTotal: (state) { return (itemId: number) { const item state.items.find(i i.id itemId) if (!item) return 0 return item.price * item.quantity * (1 - item.discount) } }, // 3️⃣ 依赖其他 getter 的链式调用 taxAmount(): number { return this.subtotal * this.taxRate }, total(): number { return this.subtotal this.taxAmount }, // 4️⃣ 返回格式化数据 formattedTotal(): string { return ¥${this.total.toFixed(2)} }, // 5️⃣ 条件过滤 排序 highValueItems(): any[] { return this.items .filter(item item.price * item.quantity 500) .sort((a, b) (b.price * b.quantity) - (a.price * a.quantity)) }, // 6️⃣ 返回统计对象 summary(): Recordstring, any { return { itemCount: this.items.length, subtotal: this.subtotal, tax: this.taxAmount, total: this.total, averageItemValue: this.subtotal / this.items.length } }, // 7️⃣ 布尔组合逻辑 hasDiscountItems(): boolean { return this.items.some(item item.discount 0) }, hasHighValueItems(): boolean { return this.items.some(item item.price * item.quantity 1000) }, // 8️⃣ 动态状态判断 isCartEligibleForFreeShipping(): boolean { return this.total 500 this.items.length 2 } } })五、五种使用方式对比表使用方式语法示例缓存特性适用场景注意事项1. 直接使用store.getterName✅ 缓存大多数场景最简单直接2. 解构使用const { getter } storeToRefs(store)✅ 缓存模板中多次使用必须用storeToRefs不能直接解构3. 传参调用store.getterName(param)❌ 不缓存需要动态参数的查询返回函数的特殊形式4. 计算属性组合computed(() store.getterA store.getterB)✅ 缓存需要组合多个 getter会创建新的依赖追踪5. 在 action 中使用actions: { submit() { const val this.getter } }✅ 缓存在 action 中复用逻辑使用this访问六、性能优化建议// ❌ 避免每次访问都创建新对象 getters: { badPractice: (state) { return { name: state.user.name, age: state.user.age, // 每次访问都返回新对象导致响应式依赖丢失 } } } // ✅ 推荐返回派生数据 getters: { goodPractice: (state) state.user.name state.user.age } // ✅ 如果确实需要返回对象考虑缓存 getters: { userProfile: (state) { // 只有 user 变化时才重新计算对象 return { fullName: ${state.user.firstName} ${state.user.lastName}, age: state.user.age, isAdult: state.user.age 18 } } }七、TypeScript 类型支持// 带类型的 getter 定义 interface Todo { id: number text: string done: boolean } interface UserState { todos: Todo[] filter: all | completed | pending } getters: { // 自动类型推导 filteredTodos(state): Todo[] { switch (state.filter) { case completed: return state.todos.filter(t t.done) case pending: return state.todos.filter(t !t.done) default: return state.todos } }, // 显式类型标注 todoStats(state): { total: number completed: number pending: number completionRate: string } { const completed state.todos.filter(t t.done).length const total state.todos.length return { total, completed, pending: total - completed, completionRate: total ? ${((completed / total) * 100).toFixed(1)}% : 0% } } }总结如何选择简单派生数据→ 基础函数形式依赖其他 getter→ this 形式需要动态参数→ 返回函数的 getter频繁使用的派生数据→ getter storeToRefs 解构一次性使用的数据→ 直接store.getterName
Pinia 中 Getters 的使用方式
Pinia中Getters的完整使用指南Getters作为计算属性支持函数形式state参数和this形式访问其他getter。典型用法包括基础状态派生、返回函数传参、条件过滤等8种场景可通过直接调用、解构或计算属性组合使用。高级技巧涉及缓存优化、类型支持和链式调用需注意返回对象时的性能问题。根据场景选择合适形式简单派生用函数形式依赖其他getter用this形式动态参数需返回函数。Pinia 中 Getters 的使用方式Pinia 的 Getters 完全等同于 Store 状态中的计算属性可以通过多种方式定义和使用。一、基础定义方式定义方式语法适用场景函数形式getterName: (state) { return ... }简单派生状态不需要 this 上下文this 形式getterName(): { return this.xxx }需要访问其他 getter 时二、完整示例演示// stores/user.ts import { defineStore } from pinia export const useUserStore defineStore(user, { state: () ({ firstName: 张, lastName: 三丰, age: 25, todos: [ { id: 1, text: 学习Pinia, done: true }, { id: 2, text: 学习Vue3, done: false }, { id: 3, text: 写代码, done: false } ] }), getters: { // 1️⃣ 基础形式使用 state fullName: (state) ${state.firstName} ${state.lastName}, // 2️⃣ 访问其他 getter使用 this fullNameWithAge(): string { return ${this.fullName}年龄${this.age} }, // 3️⃣ 返回函数动态传参注意这会缓存结果 getUserById: (state) { return (userId: number) { return state.todos.find(todo todo.id userId) } }, // 4️⃣ 已完成事项 completedTodos: (state) state.todos.filter(todo todo.done), // 5️⃣ 未完成事项使用 this 访问其他 getter pendingTodos(): any[] { return this.todos.filter((todo: any) !todo.done) }, // 6️⃣ 统计信息返回对象 todosStats(): { total: number, completed: number, pending: number } { return { total: this.todos.length, completed: this.completedTodos.length, pending: this.pendingTodos.length } }, // 7️⃣ 条件判断 isAdult: (state) state.age 18, // 8️⃣ 结合其他 getter 的复杂计算 summary(): string { const stats this.todosStats return 总共${stats.total}个任务已完成${stats.completed}个剩余${stats.pending}个 } } })三、在组件中使用 Getters 的多种方式template div !-- 1️⃣ 直接使用最常见 -- p全名{{ userStore.fullName }}/p p详细信息{{ userStore.fullNameWithAge }}/p !-- 2️⃣ 传参调用返回函数的 getter -- pID为1的事项{{ userStore.getUserById(1)?.text }}/p !-- 3️⃣ 解构使用需要配合 storeToRefs -- p是否成年{{ isAdult }}/p p任务统计{{ todosStats }}/p p摘要{{ summary }}/p !-- 4️⃣ 在计算属性中使用 -- p格式化后的信息{{ formattedInfo }}/p /div /template script setup langts import { useUserStore } from /stores/user import { storeToRefs } from pinia import { computed } from vue const userStore useUserStore() // 方式1直接使用推荐 console.log(userStore.fullName) // 方式2解构使用必须用 storeToRefs 保持响应性 const { fullName, isAdult, todosStats, summary } storeToRefs(userStore) // 方式3传参调用返回函数的 getter const todo1 userStore.getUserById(1) // 方式4在组合式函数中使用 function useUserGreeting() { const greeting computed(() { return 你好${userStore.fullName}${userStore.isAdult ? 欢迎成年用户 : 你好年轻人} }) return { greeting } } const { greeting } useUserGreeting() // 方式5结合 Vue 的计算属性 const formattedInfo computed(() { const stats userStore.todosStats return 【${userStore.fullName}】完成进度${stats.completed}/${stats.total} }) /script四、高级用法技巧// stores/advanced.ts import { defineStore } from pinia export const useAdvancedStore defineStore(advanced, { state: () ({ items: [ { id: 1, price: 100, quantity: 2, discount: 0.1 }, { id: 2, price: 200, quantity: 1, discount: 0 }, { id: 3, price: 300, quantity: 3, discount: 0.2 } ], taxRate: 0.08 }), getters: { // 1️⃣ 缓存计算结果默认行为 subtotal: (state) { console.log(计算小计...) // 只有 items 变化时才重新计算 return state.items.reduce((sum, item) { return sum (item.price * item.quantity * (1 - item.discount)) }, 0) }, // 2️⃣ 带参数的 getter返回函数 // 注意这个不会缓存结果每次调用都重新计算 getItemTotal: (state) { return (itemId: number) { const item state.items.find(i i.id itemId) if (!item) return 0 return item.price * item.quantity * (1 - item.discount) } }, // 3️⃣ 依赖其他 getter 的链式调用 taxAmount(): number { return this.subtotal * this.taxRate }, total(): number { return this.subtotal this.taxAmount }, // 4️⃣ 返回格式化数据 formattedTotal(): string { return ¥${this.total.toFixed(2)} }, // 5️⃣ 条件过滤 排序 highValueItems(): any[] { return this.items .filter(item item.price * item.quantity 500) .sort((a, b) (b.price * b.quantity) - (a.price * a.quantity)) }, // 6️⃣ 返回统计对象 summary(): Recordstring, any { return { itemCount: this.items.length, subtotal: this.subtotal, tax: this.taxAmount, total: this.total, averageItemValue: this.subtotal / this.items.length } }, // 7️⃣ 布尔组合逻辑 hasDiscountItems(): boolean { return this.items.some(item item.discount 0) }, hasHighValueItems(): boolean { return this.items.some(item item.price * item.quantity 1000) }, // 8️⃣ 动态状态判断 isCartEligibleForFreeShipping(): boolean { return this.total 500 this.items.length 2 } } })五、五种使用方式对比表使用方式语法示例缓存特性适用场景注意事项1. 直接使用store.getterName✅ 缓存大多数场景最简单直接2. 解构使用const { getter } storeToRefs(store)✅ 缓存模板中多次使用必须用storeToRefs不能直接解构3. 传参调用store.getterName(param)❌ 不缓存需要动态参数的查询返回函数的特殊形式4. 计算属性组合computed(() store.getterA store.getterB)✅ 缓存需要组合多个 getter会创建新的依赖追踪5. 在 action 中使用actions: { submit() { const val this.getter } }✅ 缓存在 action 中复用逻辑使用this访问六、性能优化建议// ❌ 避免每次访问都创建新对象 getters: { badPractice: (state) { return { name: state.user.name, age: state.user.age, // 每次访问都返回新对象导致响应式依赖丢失 } } } // ✅ 推荐返回派生数据 getters: { goodPractice: (state) state.user.name state.user.age } // ✅ 如果确实需要返回对象考虑缓存 getters: { userProfile: (state) { // 只有 user 变化时才重新计算对象 return { fullName: ${state.user.firstName} ${state.user.lastName}, age: state.user.age, isAdult: state.user.age 18 } } }七、TypeScript 类型支持// 带类型的 getter 定义 interface Todo { id: number text: string done: boolean } interface UserState { todos: Todo[] filter: all | completed | pending } getters: { // 自动类型推导 filteredTodos(state): Todo[] { switch (state.filter) { case completed: return state.todos.filter(t t.done) case pending: return state.todos.filter(t !t.done) default: return state.todos } }, // 显式类型标注 todoStats(state): { total: number completed: number pending: number completionRate: string } { const completed state.todos.filter(t t.done).length const total state.todos.length return { total, completed, pending: total - completed, completionRate: total ? ${((completed / total) * 100).toFixed(1)}% : 0% } } }总结如何选择简单派生数据→ 基础函数形式依赖其他 getter→ this 形式需要动态参数→ 返回函数的 getter频繁使用的派生数据→ getter storeToRefs 解构一次性使用的数据→ 直接store.getterName