Vue-tables-2 (vuex) реактивность не работает

у меня есть несколько компонентов, использующих vue-таблицы-2 но один из них не обновляет таблицу, пока я не изменю маршрут.

компонент

    <template>
//..
    <div class="table-responsive" >
       <v-client-table ref="table" name="vCardTable" 
          :data="vCardTableData.data" 
          :columns="vCardTableData.headers" 
          :options="vCardTableData.options"/>
    </div> 
//..
    </template>
<script>
import { mapState } from "vuex";
import { mapGetters } from "vuex";

export default {
  name: "VCard",
  computed: {
    ...mapState("commons", ["user"]),
    ...mapGetters({ vCardTableData: "vCard/vCardTableData" })
  },
  mounted() {
    var self = this;
    self.$nextTick(() => {
      self.$store.dispatch("vCard/getVCards"); <-- GET TABLE DATA
    });
  }
};
</script>

магазине

const state = {
    vCardTableData: {
        data: [],
        headers: [
           //..
        ],
        options: {
            filterable: false,
            preserveState: false,
            headings: {
                //..
            },
            texts: {
                //..
            },
            pagination: {
                dropdown: true,
            },
            templates: {
                //..
            },
        },
    }
}

const getters = {
    vCardTableData: state => state.vCardTableData
}

const actions = {
    getVCards({commit, dispatch}) {
            return api.request("get", "getvcards").then(response => {
                setTimeout(() => {  
                    commit("setVCardTableData", response.data.vcards);
                }, 300);
            }).catch(error => {
                console.log(error);
            });
    }
}

const mutations = {
    clearTableData: (state) => {
        if (state.vCardTableData.data) {
            state.vCardTableData.data = [];
        }
    },
    setVCardTableData : (state, vCardTableData) => state.vCardTableData.data = vCardTableData   
}

как вы можете видеть на этом изображении в таблице есть данные:

enter image description here Но представление обновляется при изменении маршрута:

enter image description here

02/05/2018

Ну, теперь я видел, что, если я изменю состояние непосредственно в компоненте с обещаниями, он работает:

this.$store.dispatch("vCard/getVCards", []).then((responseData)=>{
       this.$store.state.vCard.vCardTableData.data = responseData;
  }); 

кто-нибудь знает почему? Спасибо

4 ответов


мой последний ответ был неправильным, я не помнил, что изменил vuex параметр таблицы в false. Я не знаю, почему, но делая толчок, он работает:

setVCardTableData : (state, vCardTableData) => {
    vCardTableData.forEach(tableData => {
            state.vCardTableData.data.push(tableData);   
    });
} 

это, вероятно, проблема реактивности. (См.https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats для детального объяснения.)

изменение способа установки значения объекта в вашей мутации на это должно решить проблему

setVCardTableData: (state, vCardTableData) => state.vCardTableData = {
    ...state.vCardTableData,
    data: vCardTableData
}

в основном, это создает новый объект, так что Vue знает, что объект был обновлен. В Javasript объект передается по ссылке, что означает, что vCardTableData Не храните объект, он хранит ссылка на объект. Вы можете думать об этом как о указателе/адресе, который указывает на объект в памяти. При изменении дочернего свойства в объекте ссылка остается неизменной, поэтому Vue не знает, что объект был обновлен. Создание нового объекта гарантирует обновление ссылки на объект.

это также объясняется в мутации следуют правилам реактивности Vue в https://vuex.vuejs.org/en/mutations.html


поскольку это глубокий объект, вам нужно использовать Object.назначьте в вашей мутации

setVCardTableData: (state, vCardTableData) => Object.assign(state.vCardTableData.data, vCardTableData)

у меня были похожие проблемы. Как и другие уже упоминали, это, вероятно, проблема реактивности. Вы можете использовать Vue.set() чтобы убедиться, что ваши свойства реагируют при установке значений состояния.

setVCardTableData: (state, vCardTableData) => {
    Vue.set(state.vCardTableData, 'data', vCardTableData);
}

Регистрация официальная документация для этого метода.