Vue-tables-2(vuex)反应性不起作用
Vue-tables-2(vuex) reactivity not working
我有几个使用 vue-tables-2 的组件,但在我更改路线之前,其中之一不会更新 table。
分量
<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
}
正如您在此图像中所见,table 具有数据:
但是当路由改变时视图会刷新:
02/05/2018
现在我已经看到,如果我直接在组件中使用 promises 修改状态,它会起作用:
this.$store.dispatch("vCard/getVCards", []).then((responseData)=>{
this.$store.state.vCard.vCardTableData.data = responseData;
});
有人知道为什么吗?
谢谢
这可能是一个反应性问题。 (详见https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats。)
改变你在突变中设置对象值的方式应该可以解决问题
setVCardTableData: (state, vCardTableData) => state.vCardTableData = {
...state.vCardTableData,
data: vCardTableData
}
基本上,这会创建一个新对象,以便 Vue 知道该对象已更新。在 Javasript 中,对象是通过引用传递的,这意味着 vCardTableData
不存储对象,它存储对对象的引用。您可以将其视为指向内存中对象的 pointer/address。当你改变对象中的一个child 属性时,引用保持不变,所以Vue不知道这个对象已经更新了。创建新对象可确保更新对象引用。
这在Mutations Follow Vue's Reactivity Rules中也有解释
在 https://vuex.vuejs.org/en/mutations.html
因为它是一个深层对象,你需要在你的 mutation
中使用 Object.assign
setVCardTableData: (state, vCardTableData) => Object.assign(state.vCardTableData.data, vCardTableData)
我遇到过类似的问题。就像其他人已经提到的那样,这可能是一个反应性问题。您可以使用 Vue.set()
来确保您的属性在设置状态值时是反应性的。
setVCardTableData: (state, vCardTableData) => {
Vue.set(state.vCardTableData, 'data', vCardTableData);
}
检查此方法的 official documentation。
我最后的回答错了,我不记得我把table的vuex
参数改成了false。我不知道为什么,但推动它有效:
setVCardTableData : (state, vCardTableData) => {
vCardTableData.forEach(tableData => {
state.vCardTableData.data.push(tableData);
});
}
我有几个使用 vue-tables-2 的组件,但在我更改路线之前,其中之一不会更新 table。
分量
<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
}
正如您在此图像中所见,table 具有数据:
02/05/2018
现在我已经看到,如果我直接在组件中使用 promises 修改状态,它会起作用:
this.$store.dispatch("vCard/getVCards", []).then((responseData)=>{
this.$store.state.vCard.vCardTableData.data = responseData;
});
有人知道为什么吗? 谢谢
这可能是一个反应性问题。 (详见https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats。)
改变你在突变中设置对象值的方式应该可以解决问题
setVCardTableData: (state, vCardTableData) => state.vCardTableData = {
...state.vCardTableData,
data: vCardTableData
}
基本上,这会创建一个新对象,以便 Vue 知道该对象已更新。在 Javasript 中,对象是通过引用传递的,这意味着 vCardTableData
不存储对象,它存储对对象的引用。您可以将其视为指向内存中对象的 pointer/address。当你改变对象中的一个child 属性时,引用保持不变,所以Vue不知道这个对象已经更新了。创建新对象可确保更新对象引用。
这在Mutations Follow Vue's Reactivity Rules中也有解释 在 https://vuex.vuejs.org/en/mutations.html
因为它是一个深层对象,你需要在你的 mutation
中使用 Object.assignsetVCardTableData: (state, vCardTableData) => Object.assign(state.vCardTableData.data, vCardTableData)
我遇到过类似的问题。就像其他人已经提到的那样,这可能是一个反应性问题。您可以使用 Vue.set()
来确保您的属性在设置状态值时是反应性的。
setVCardTableData: (state, vCardTableData) => {
Vue.set(state.vCardTableData, 'data', vCardTableData);
}
检查此方法的 official documentation。
我最后的回答错了,我不记得我把table的vuex
参数改成了false。我不知道为什么,但推动它有效:
setVCardTableData : (state, vCardTableData) => {
vCardTableData.forEach(tableData => {
state.vCardTableData.data.push(tableData);
});
}