为什么状态不在 vuex 中更新?
Why is state not updating in vuex?
我正在使用带有 axios 的 vuex 从后端获取数据。当我控制台记录状态时,它会显示更新后的状态。但是,我调用状态时总是没有数据。我错过了什么吗?
vuex文件
import axios from "axios";
import { uid } from "quasar";
const state = {
data: {},
};
const mutations = {
addData(state, payload) {
state.data[payload.id] = payload.data;
console.log(state.data); //the data exist
},
};
const actions = {
readData({ commit }) {
axios({
method: "get",
url:
"https://dev.activate.vi9e.com/api/purchase/receivegoods/index?action=list",
headers: {
"Content-Type": "application/json",
},
})
.then((response) => {
for (var i = 0; i < response.data.length - 1; i++) {
let dataId = uid();
let payload = {
id: dataId,
data: response.data[i],
};
commit("addData", payload);
}
})
.catch((error) => {
//handle error
console.log("error message: ", error.message);
});
},
};
const getters = {
data: (state) => {
return state.data;
},
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};
这是我的模板:
<template>
<p>{{ data }}</p>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
methods: {
...mapActions("incominggoods", ["readData"]),
},
computed: {
...mapGetters("incominggoods", ["data"]),
},
mounted() {
this.readData();
}
};
</script>
尽管如此,每当我在控制台登录突变时我都会获取数据,但状态中的数据根本没有更新。我该如何解决这个问题?
解决方案
感谢所有的评论。它们都值得解决问题。问题是由于 vue 的反应性。 Vue貌似不允许处理“对象”(非原始数据类型),也不允许通过数组赋值的方式来处理“对象”。这是我根据评论所做的:
- 我手动操作了从后端接收到的数据(其中它具有“对象数据类型”(非原始数据类型)并将其更改为“对象数据类型”)。
在行动中(然后(响应))
for (var i = 0; i < response.data.length; i++) {
let dataId = uid();
// manipulate the "object" to "Object"
let data = {
poid: response.data[i].purchase_order_id,
podate: response.data[i].po_date,
vendor: response.data[i].vendor_name,
qty: "0%",
total_qty_ordered: response.data[i].total_qty_ordered,
total_qty_receivable: response.data[i].total_qty_receivable,
total_qty_received: response.data[i].total_qty_received,
status: response.data[i].status,
barcode: response.data[i].purchase_order_id,
printed_id: response.data[i].printed_id,
};
// END OF THE MANIPULATION
let payload = {
id: dataId,
data: data,
};
commit("addData", payload);
突变中
addData(state, payload) {
Vue.set(state.data, payload.id, payload.data);
},
Vue 的反应系统无法检测对象 属性 添加,请参阅 Reactivity in Depth。
在你的突变中,改变这个
state.data[payload.id] = payload.data;
对此:
Vue.set(state.data, payload.id, payload.data);
JS 对非原始类型(对象和数组,进一步阅读中的对象)的反应有点奇怪。
把一个对象想象成一辆有色 windows 的公共汽车。如果一个乘客(数组中的项目或对象中的 key/value)或乘客进出公共汽车,而你从街上看它,你不知道发生了什么变化,公共汽车仍然看起来一样。这基本上就是它的工作原理,您有 2 个对象反应性选项。
您可以:
a) 替换整个对象
b) 在 Vue 的情况下,使用 Vue.set(对于实际对象,而不是数组)
选项 a) 如下所示:
// for objects
const addObjectProperty = (state, property) => {
state.object = {...state.object, property)
}
// for arrays
const addArrayItem = (state, item) => {
state.array = [...state.array, item]
}
这是在做什么,是使用对象文字语法({ } 或 [ ])即时创建一个新对象。所以这样,Vue 正在查看你的 state.object,并看到它被一个全新的替换并做出相应的反应。
选项 b) 如下所示:
const addObjectProperty = (state, property) => {
// Vue.set params: object, key, value
Vue.set(state.object, state.object[property], property)
}
关于数组,直接使用数组方法即可,不要像arr[x] = 10
那样手动更改值,那样也会导致同样的问题。
编辑:
如果你有一个嵌套对象作为状态属性,你仍然需要替换顶级对象。
state: {
this: {},
is: {},
what: {},
you: {},
need: {},
to: {},
change: {},
not: {
this: {}
}
}
}
如果你有很多嵌套状态,最简单的方法是使用 vuex modules
我正在使用带有 axios 的 vuex 从后端获取数据。当我控制台记录状态时,它会显示更新后的状态。但是,我调用状态时总是没有数据。我错过了什么吗?
vuex文件
import axios from "axios";
import { uid } from "quasar";
const state = {
data: {},
};
const mutations = {
addData(state, payload) {
state.data[payload.id] = payload.data;
console.log(state.data); //the data exist
},
};
const actions = {
readData({ commit }) {
axios({
method: "get",
url:
"https://dev.activate.vi9e.com/api/purchase/receivegoods/index?action=list",
headers: {
"Content-Type": "application/json",
},
})
.then((response) => {
for (var i = 0; i < response.data.length - 1; i++) {
let dataId = uid();
let payload = {
id: dataId,
data: response.data[i],
};
commit("addData", payload);
}
})
.catch((error) => {
//handle error
console.log("error message: ", error.message);
});
},
};
const getters = {
data: (state) => {
return state.data;
},
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};
这是我的模板:
<template>
<p>{{ data }}</p>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
methods: {
...mapActions("incominggoods", ["readData"]),
},
computed: {
...mapGetters("incominggoods", ["data"]),
},
mounted() {
this.readData();
}
};
</script>
尽管如此,每当我在控制台登录突变时我都会获取数据,但状态中的数据根本没有更新。我该如何解决这个问题?
解决方案 感谢所有的评论。它们都值得解决问题。问题是由于 vue 的反应性。 Vue貌似不允许处理“对象”(非原始数据类型),也不允许通过数组赋值的方式来处理“对象”。这是我根据评论所做的:
- 我手动操作了从后端接收到的数据(其中它具有“对象数据类型”(非原始数据类型)并将其更改为“对象数据类型”)。
在行动中(然后(响应))
for (var i = 0; i < response.data.length; i++) {
let dataId = uid();
// manipulate the "object" to "Object"
let data = {
poid: response.data[i].purchase_order_id,
podate: response.data[i].po_date,
vendor: response.data[i].vendor_name,
qty: "0%",
total_qty_ordered: response.data[i].total_qty_ordered,
total_qty_receivable: response.data[i].total_qty_receivable,
total_qty_received: response.data[i].total_qty_received,
status: response.data[i].status,
barcode: response.data[i].purchase_order_id,
printed_id: response.data[i].printed_id,
};
// END OF THE MANIPULATION
let payload = {
id: dataId,
data: data,
};
commit("addData", payload);
突变中
addData(state, payload) {
Vue.set(state.data, payload.id, payload.data);
},
Vue 的反应系统无法检测对象 属性 添加,请参阅 Reactivity in Depth。
在你的突变中,改变这个
state.data[payload.id] = payload.data;
对此:
Vue.set(state.data, payload.id, payload.data);
JS 对非原始类型(对象和数组,进一步阅读中的对象)的反应有点奇怪。 把一个对象想象成一辆有色 windows 的公共汽车。如果一个乘客(数组中的项目或对象中的 key/value)或乘客进出公共汽车,而你从街上看它,你不知道发生了什么变化,公共汽车仍然看起来一样。这基本上就是它的工作原理,您有 2 个对象反应性选项。
您可以:
a) 替换整个对象
b) 在 Vue 的情况下,使用 Vue.set(对于实际对象,而不是数组)
选项 a) 如下所示:
// for objects
const addObjectProperty = (state, property) => {
state.object = {...state.object, property)
}
// for arrays
const addArrayItem = (state, item) => {
state.array = [...state.array, item]
}
这是在做什么,是使用对象文字语法({ } 或 [ ])即时创建一个新对象。所以这样,Vue 正在查看你的 state.object,并看到它被一个全新的替换并做出相应的反应。
选项 b) 如下所示:
const addObjectProperty = (state, property) => {
// Vue.set params: object, key, value
Vue.set(state.object, state.object[property], property)
}
关于数组,直接使用数组方法即可,不要像arr[x] = 10
那样手动更改值,那样也会导致同样的问题。
编辑: 如果你有一个嵌套对象作为状态属性,你仍然需要替换顶级对象。
state: {
this: {},
is: {},
what: {},
you: {},
need: {},
to: {},
change: {},
not: {
this: {}
}
}
}
如果你有很多嵌套状态,最简单的方法是使用 vuex modules