• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • getter

    有时候我们需要从store中的state中派生出一些状态,例如对列表进行过滤并计数:

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

    如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。

    Vuex 允许我们在store中定义getters(可以认为是store的计算属性)。就像计算属性一样,getters的返回值,会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

    getter接受state作为其第一个参数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也可以接受getter其他的值,作为第二个参数

    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)
        }
        doneTodosCount (state, getters) {
          return getters.doneTodos.length      //通过getter访问到doneTodos属性
        }
      }
    })
    


    通过属性访问

    getter会暴露为store.getters对象,你可以以属性的形式访问这些值:

    store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
    store.getters.doneTodosCount // -> 1
    

    我们可以很容易地在任何组件中使用它:

    computed: {
      doneTodosCount () {
        return this.store.getters.doneTodosCount
      }
    }
    

    注意:getter在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。


    通过方法访问

    你也可以通过让getter返回一个函数,来实现给getter传参。在你对store里的数组,进行查询时,非常有用。

    const store = createStore({
      state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
      },
      getters: {
        // ...
        getTodoById: (state) => (id) => {
          return state.todos.find(todo => todo.id === id)
        }
      }
    })
    
    store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
    

    注意,getter通过方法访问时,每次都会去进行调用,而不会缓存结果


    上例子中,不使用箭头函数, getTodoById函数的写法:

    getTodoById: function(state, getters) {
      return function(id) {
        return state.todos.find(function(todo)  {
          return todo.id === id;
        })
      }
    }
    


    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'
    })
    

    上篇:state

    下篇:mutation