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
}
как вы можете видеть на этом изображении в таблице есть данные:
Но представление обновляется при изменении маршрута:
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);
}
Регистрация официальная документация для этого метода.