Vuex - 更新整个数组

新手上路,请多包涵

我有一个 Vue.js 应用程序。这个应用程序使用 Vuex 进行状态管理。我的商店是这样的:

 const store = new Vuex.Store({
    state: {
        items: []
    },

    mutations: {
        MUTATE_ITEMS: (state, items) => {
            state.items = items;
        }
    },

    actions: {
        loadItems: (context, items) => {
            context.commit('MUTATE_ITEMS', items);
        }
    }
  })
;

在我的 Vue 实例中,我有以下方法:

 loadItems() {

  let items = [];
  for (let I=0; I<10; I++) {
    items.push({ id:(I+1), name: 'Item #' + (I+1) });
  }
  this.$store.dispatch('loadItems', items);
},

当我运行它时,我注意到我的子组件中的项目列表没有得到更新。我怀疑这是因为 Vue.js 中的反应性模型。但是,我不确定如何更新整个数组。此外,我不确定是否需要在我的存储突变、存储操作或 Vue 实例方法本身中使用 Vue.set 。我有点困惑。

零件:

 <template>
    <div>
        <h1>Items ({{ items.length }})</h1>
        <table>
            <tbody>
                <tr v-for="item in items" :key="item.id">
                    <td>{{ item.id }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
    import { mapState } from 'vuex';

    export default {
        computed: mapState({
            items: state => state.items
        })
    };
</script>

如何在 Vue.js 应用程序中更新集中存储在 Vuex 中的整个数组?

原文由 Some User 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 815
2 个回答

使用vue的 set 功能。这将确保 Vue 的反应性启动并更新所需的对象。

 import Vuex from 'vuex';
const store = new Vuex.Store({
    state: {
        items: []
    },

    mutations: {
        MUTATE_ITEMS: (state, items) => {
            Vue.set(state, 'items', items);
            // or, better yet create a copy of the array
            Vue.set(state, 'items', [...items]);
        }
    },

    actions: {
        loadItems: (context, items) => {
            context.commit('MUTATE_ITEMS', items);
        }
    }
  })
;

在处理数组或对象时,防止可变性是一个好主意,我通常使用扩展运算符 {...myObject}[..myArray] 这将防止对来自其他来源的对象进行更改你的来源,所以在 getter 中实现也是一个好主意。


更新:

这是一个工作示例: https ://codesandbox.io/s/54on2mpkn(codesandbox 允许您拥有单个文件组件)

我注意到的是您没有任何 getter ,它们有助于获取数据。您可以直接使用计算值或使用 mapGetters 调用它们。但它们不是强制性的。获取数据的三种方式

<script>
import { mapGetters } from "vuex";
import Item from "./Item";

export default {
  name: "ItemList",
  components: {
    Item
  },
  computed: {
    ...mapGetters(["items"]), // <-- using mapGetters
    itemsGet() {    // <-- using getter, but not mapGetters
      return this.$store.getters.items;
    },
    itemsDirect() {  // <--no getter, just store listener
      return this.$store.state.items;
    }
  }
};
</script>

从功能的角度来看,您选择哪一个并不重要,但使用 getter 可以使代码更易于维护。

原文由 Daniel 发布,翻译遵循 CC BY-SA 4.0 许可协议

您需要像以下任何一种一样调度操作:

 // dispatch with a payload
this.$store.dispatch('loadItems', {items})

// dispatch with an object
this.$store.dispatch({type: 'loadItems',items})

原文由 Bhojendra Rauniyar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题