Vuex getter 每个项目

Vuex getter for each item

我正在尝试找出一种方法来为 Vuex 存储中的每个项目添加计算的 属性 数组。例如,在 Todo 列表应用程序中,每个 Todo 项目都可能有 DueDate 和一个 Completed 标志。基于这些属性,我们可以计算 Todo 项目是否逾期。

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
    state: {
        Todos: []
    },
    mutations: { /* ... */ },
    actions: {/* ... */ } 
);

let exampleTodo = {
    Title: 'Go grocery shopping',
    Completed: false,
    DueDate: new Date("10/12/2017")
};

到目前为止,我一直在使用 mapState 在组件级别添加计算的 属性,如下所示:

computed: {
    ...mapState({
        todos: state => state.Todos.map(t => {
            // Add some computed fields
            return {
                ...t,
                OverDue: !t.Completed && Date.now() > t.DueDate
            };
        })
    })
}

但这意味着需要对每个组件进行计算。对于这么简单的事情,这没什么大不了的,但对于更复杂的计算,我宁愿将它们放在一个地方。有没有办法在商店中完成此操作,还是我应该继续使用此模式?或者还有什么我想念的吗?

您可以制作一个 getter 来在 Vuex 存储中进行映射。 getter 函数在第一次被访问时将是 运行(及其缓存的 returned 值)。对该 getter 的任何后续引用都将 return 缓存值,除非依赖状态已更新,在这种情况下 getter 函数将再次 运行。

Here's the documentation on Vuex getters.

这是一个例子:

const store = new Vuex.Store({
  state: {
    todos: []
  },
  mutations: { 
    SET_TODOS(state, todos) {
      state.todos = todos;
    }
  },
  getters: {
    todos(state) {
      return state.todos.map(t => {
        return {
          ...t,
          OverDue: !t.Completed && Date.now() > t.DueDate
        }
      })
    }
  }
})

new Vue({
  el: '#app',
  store,
  created() {
    let todos = [{
      Title: 'Go grocery shopping',
      Completed: false,
      DueDate: new Date("10/12/2017")
    }, {
      Title: 'Get a haircut',
      Completed: false,
      DueDate: new Date("10/10/2017")
    }];
    
    this.$store.commit('SET_TODOS', todos)
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.4.1/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script>

<div id="app">
  {{ $store.getters.todos }}
</div>