将计算逻辑放在 getters 还是 actions 里,取决于具体的使用场景和需求,下面详细分析放在 getters 中的优势以及和 actions 的区别,以说明是否有必要放在 getters 里:
1. getters 的优势
缓存特性
getters 具有类似 Vue 计算属性的缓存机制。只有当它依赖的状态发生变化时,才会重新计算结果。例如在之前的 sum 计算中,只要 state.numbers 数组不改变,sum 就不会重新计算,直接返回之前缓存的结果。
javascript">import { defineStore } from 'pinia';export const useMyStore = defineStore('myStore', {state: () => ({numbers: [1, 2, 3]}),getters: {sum: (state) => state.numbers.reduce((acc, num) => acc + num, 0)}
});
在组件中多次访问 store.sum 时,如果 numbers 数组没有变化,就不会重复执行 reduce 计算,提高了性能。
数据派生与展示
getters 主要用于从现有的状态中派生出新的数据,适合用于数据展示相关的计算。在组件里,getters 可以像普通状态一样被使用,方便在模板中展示计算结果。
<template><div><p>Sum: {{ sumValue }}</p></div>
</template><script setup>
import { useMyStore } from '../stores/myStore';
import { storeToRefs } from 'pinia';const store = useMyStore();
const { sum: sumValue } = storeToRefs(store);
</script>
代码复用与可维护性
将计算逻辑封装在 getters 中,使得代码更具复用性和可维护性。如果多个组件都需要用到 sum 的计算结果,只需要在 getters 中定义一次,各个组件都可以直接使用。当 numbers 数组的计算逻辑发生变化时,只需要修改 getters 中的 sum 方法即可。
2. actions 的特点
actions 通常用于处理异步操作或者修改 store 中的状态。它可以包含复杂的业务逻辑,比如发起网络请求、处理用户输入等。与 getters 不同,actions 不具备缓存特性,每次调用都会执行其中的代码。
javascript">import { defineStore } from 'pinia';export const useMyStore = defineStore('myStore', {state: () => ({numbers: [1, 2, 3]}),actions: {calculateSum() {return this.numbers.reduce((acc, num) => acc + num, 0);}}
});
<template><div><p>Sum: {{ sumValue }}</p></div>
</template><script setup>
import { useMyStore } from '../stores/myStore';const store = useMyStore();
const sumValue = store.calculateSum();
</script>
在这个例子中,每次调用 store.calculateSum() 都会重新执行 reduce 计算,没有缓存机制。
总结
如果计算逻辑只是简单地从现有的状态中派生出新的数据,并且希望利用缓存机制提高性能,方便在组件中展示计算结果,那么将其放在 getters 中是合适的。而如果计算逻辑涉及到异步操作、修改状态或者复杂的业务逻辑,那么应该放在 actions 中。