Vuex 核心概念之 Getter
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:
<div>{{doneTodosCount}}</div>
computed: {
doneTodosCount() {
return this.$store.state.todos.filter(todo => todo.done).lenth
}
}
如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。
Getter 接受 state 作为其第一个参数:
const state = {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
}
const getters = {
doneTodos(state) {
return state.todos.filter(todo => todo.done) // [{ id: 1, text: '...', done: true }]
}
}
// 创建store并暴露store
export const store = new Vuex.Store({
state: state,
getters: getters
})
在组件中如何访问呢?
// count.vue
<div>{{doneTodos}}<div>
computed: {
doneTodos(){
return this.$store.getters.doneTodos // [{ id: 1, text: '...', done: true }]
}
}
Getter 也可以接受其它getter作为第二个参数
const state = {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
}
const getters = {
doneTodos(state) {
return state.todos.filter(todo => todo.done)
},
// 接受其它的getter作为第二个参数
doneTodosCount(state, getters) {
return getters.doneTodos.length // 1
}
}
// 创建store并暴露store
export const store = new Vuex.Store({
state: state,
getters: getters
})
// count.vue
<div>{{doneTodosCount}}<div>
computed: {
doneTodosCount(){
return this.$store.getters.doneTodosCount // 1
}
}
getter 也可以返回一个函数
让getter
返回一个函数,在你对store
里的数组进行查询的时候非常有用
const state = {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
}
const getters = {
getTodoById: (state)=>(id)=>{
return state.todos.find(todo => todo.id === id)
}
}
// 创建store并暴露store
export const store = new Vuex.Store({
state: state,
getters: getters
})
// count.vue
<div>{{findTodos}}</div>
computed: {
findTodos() {
return this.$store.getter.getTodoById(2)
}
}
注意:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
mapGetters
辅助函数
mapGetters
辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
// count.vue
<template>
<div>{{doneTodosCount}}<div>
</template>
<script>
import {mapGetters} from '
export default {
name: 'Count',
computed: {
// 普通的写法
doneTodosCount() {
return this.$store.getters.doneTodosCount
}
// 借助mapGetters 数组写法
...mapGetters([doneTodosCount']) // 会被映射成上面的普通写法
}
}
</script>
如果你想将一个 getter 属性另取一个名字,使用对象形式:
<div>{{countLength}}</div>
computed: {
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
countLength: 'doneTodosCount'
})
}