我在vuex中使用vue,而我只花了几个小时来查找问题。也许你可以帮忙。
我的问题是,为什么我使用 CreateTeam.vue 中的newTeam
方法创建新团队,而又使用 Team.vue 中的listOfTeams
>也已更新?
listOfTeams
会更新?这是我的 Team.vue
data() {
return { listOfTeams: [] }
},
methods: {
loadRecord: async function() {
const response = await this.$store.dispatch("teams/load");
this.$store.commit("teams/intitialize", response.data);
this.listOfTeams = response.data;
}
},
CreateTeam.vue
methods: {
newTeam: async function() {
const response = await this.$store.dispatch("team/store", formData);
this.$store.commit("teams/add", response.data);
}
}
这里是我正在使用的 teams.js(模块)
const state = { record: {}, };
const actions = {
store({commit,state}, payload) { return httpFile().post('/teams', payload); },
load({ commit, state }, payload = "") { return http().get("teams" + payload); }
};
const mutations = {
intitialize(state, payload) { state.record = payload.data.data; },
add(state, payload) { state.record.unshift(payload.data); },
};
答案 0 :(得分:2)
JavaScript是一种基于参考的语言(最简单的思考方式是所有变量和成员都是指针)。
这意味着例如
let x = [];
let a = {y: x}; // Doesn't make a copy of x
console.log(a.y.length); // output is 0
x.push(10);
console.log(a.y.length); // output is 1
a.y
在创建后为空,但是该成员仍指向与x
相同的数组,因此向x
添加元素也会向a.y
添加元素,因为它们都是指向同一对象的指针。
在您的代码中
this.listOfTeams = response.data;
不会复制response.data
,因此,如果该对象被修改(例如,将其清空,并向其添加新值而不是创建新的新鲜数组),那么您的成员也会被更改。
要解决此问题,您可以编写:
this.listOfTeams = response.data.slice();
这样,您的成员类将拥有自己的数组,并且将不会依赖分配给response.data
的其他代码。
答案 1 :(得分:1)
这是一个JavaScript对象参考问题。
您从某个异步HTTP调用中获得了响应,该响应存储在response
变量(一个对象)中
您通过data
变异将该对象(以及它的intitialize
属性)提交到商店中
state.record = payload.data.data
在这里,payload.data
和response.data
是同一对象
然后将您的团队列表data
设置为同一对象
this.listOfTeams = response.data
在任何时候您都不会破坏对象引用,因此当您下次添加带有add
突变的新团队时,它将直接使用Array.prototype.unshift()
来操纵商店数据...
state.record.unshift(payload.data)
您要更改response.data.data
,this.listOfTeams
和state.record
的全部三个,因为它们都是相同的对象引用。
这就是为什么在进行直接分配时最好将您的商店状态视为不可变以及中断对象引用
const mutations = {
intitialize (state, { data }) {
state.record = {...data.data} // break reference via spread
},
add(state, { data }) {
state.record = [data, ...state.record] // immutable
}
}
答案 2 :(得分:0)
如果您正在或将要使用lodash,则可以尝试使用_.cloneDeep中断引用并根据上一个引用创建新值