有時候我們需要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾並計數:
computed: { doneTodosCount () { return this.$store.state.todos.filter(todo => todo.done).length } }
如果有多個組件需要用到此屬性,我們要么復制這個函數,或者抽取到一個共享函數然后在多處導入它——無論哪種方式都不是很理想。
Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。
Getter 接受 state 作為其第一個參數:
const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } })
通過屬性訪問
Getter 會暴露為 store.getters
對象,你可以以屬性的形式訪問這些值:
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Getter 也可以接受其他 getter 作為第二個參數:
getters: { // ... doneTodosCount: (state, getters) => { return getters.doneTodos.length } }
store.getters.doneTodosCount // -> 1
我們可以很容易地在任何組件中使用它:
computed: { doneTodosCount () { return this.$store.getters.doneTodosCount } }
注意,getter 在通過屬性訪問時是作為 Vue 的響應式系統的一部分緩存其中的。
通過方法訪問
你也可以通過讓 getter 返回一個函數,來實現給 getter 傳參。在你對 store 里的數組進行查詢時非常有用。
getters: { // ... getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } }
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
注意,getter 在通過方法訪問時,每次都會去進行調用,而不會緩存結果。
mapGetters
輔助函數
mapGetters
輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性:
import { mapGetters } from 'vuex' export default { // ... computed: { // 使用對象展開運算符將 getter 混入 computed 對象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }
如果你想將一個 getter 屬性另取一個名字,使用對象形式:
...mapGetters({ // 把 `this.doneCount` 映射為 `this.$store.getters.doneTodosCount` doneCount: 'doneTodosCount' })