Vuex好難-Getter

KY
3 min readApr 13, 2022

有時候我們需要從 store 中的 state 中派出一些狀態,例如對列表進行過濾並計數:

computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}

如果有多個組件需要用到此屬性,我們要麼複製這個函數,或著抽取到一個共享函數然後在多處導入它 — -無論哪種方式都不是很理想。

Vuex 允許我們在 store 中定義 “getter” (可以認為是 store 的計算屬性)

注意!從 Vue3.0 開始,getter 的結果不再像計算屬性一樣會被緩存起來。這是一個已知的問題,將會在 3.2 版本中修復。詳情請看 PR #1878

Getter 接受 state 作為其第一個參數:

const store = createStore({
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'
})

--

--