Vuex - обновить весь массив - PullRequest
0 голосов
/ 08 июня 2018

У меня есть приложение 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.set в мутации моего хранилища, в действии хранилища или в самом методе экземпляра Vue.Я немного сбит с толку.

Компонент:

<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>

Как обновить весь массив, централизованно хранящийся в Vuex, в приложении Vue.js?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

используйте функцию 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], это предотвратит изменения объекта из другого источника визмените ваш источник, так что это хорошая идея, чтобы реализовать его и в геттерах.


Обновление:

Вот рабочий пример: https://codesandbox.io/s/54on2mpkn (codesandbox позволяет вам иметькомпоненты одного файла)

Я заметил, что у вас нет геттеров , которые помогают получить данные.Вы можете вызывать их, используя вычисленные значения напрямую или используя 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>

. Неважно, какой из них вы выбрали с точки зрения функциональности, но использование геттеров делает код более понятным.

0 голосов
/ 08 июня 2018

Вам необходимо отправить действие, как любое из следующего:

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

// dispatch with an object
this.$store.dispatch({type: 'loadItems',items})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...