更新数组中的项目会更新所有项目
Updating an item in an array updates them all
我正在开发一个使用 vuejs 和 vuex 的应用程序,它使用项目,每个项目都有一个或多个作业。
我可以添加、删除和更新作业。添加和删除工作完美,但更新不是。
vuex 开发工具中的状态:
我的HTML:
<div class="job-compact row" v-for="(job, index) in project.jobs">
<div class="col-md-6">
<div class="form-group" :class="{'has-error' : errors.has('jobs.' + index + '.function')}">
<input type="text" name="jobs[function][]" class="form-control" v-model="job.function" @change="updateJobValue(index, 'function', $event.target.value)"/>
</div>
</div>
<div class="col-md-4">
<div class="form-group" :class="{'has-error' : errors.has('jobs.' + index + '.profiles')}">
<input type="number" name="jobs[profiles][]" class="form-control" v-model="job.profiles" @change="updateJobValue(index, 'profiles', $event.target.value)"/>
</div>
</div>
<div class="col-md-2">
<button v-if="index == 0" class="btn btn-success btn-sm" @click="addJob"><i class="fa fa-plus"></i></button>
<button v-if="index > 0" class="btn btn-danger btn-sm" @click="deleteJob(index);"><i class="fa fa-minus"></i></button>
</div>
</div>
如您所见,我有一个 v-for
显示了我所有的工作。在我的作业中编辑值时,我使用 @change
事件来更新我的值。而且,在底部,我有两个按钮可以添加和删除作业行。
我的商店分为模块。主店长这样:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state = {};
const getters = {};
const mutations = {};
const actions = {};
//Separate Module States
import jobCreator from './modules/job-creator/store';
export default new Vuex.Store({
modules: {
jobCreator: jobCreator
},
state,
actions,
mutations,
getters
});
这个特定问题的模块存储:
import store from './../../store'
const state = {
project: {
title: null,
description: null,
jobs: []
},
defaultJob: {
function: '',
title: '',
description: '',
profiles: 1,
location_id: '',
category_id: '',
budget: '',
},
};
const getters = {}
const mutations = {
addJob(state, job) {
state.project.jobs.push(job);
},
deleteJob(state, index) {
state.project.jobs.splice(index, 1);
},
updateJobValue(state, params) {
Object.assign(state.project.jobs[params.jobIndex], {
[params.field]: params.value
});
}
};
const actions = {
addJob: function (context) {
context.commit('addJob', state.defaultJob);
},
deleteJob: function (context, index) {
context.commit('deleteJob', index);
},
updateJobValue: function (context, params) {
context.commit('updateJobValue', params);
},
};
const module = {
state,
getters,
mutations,
actions
};
export default module;
项目状态映射到我的 vue 实例的计算 属性:
computed: {
...mapState({
project: state => state.jobCreator.project,
}),
}
问题如下:在应用程序的图像中,您可以看到我在其中一个字段中输入了 "vin",但所有字段都在更新。
因此,所有 作业的所有 function
字段已更新为我的最后一个条目,而不仅仅是我想要的一个。
我做错了什么?
PS:
我还在我的突变函数中尝试了以下方法:
updateJobValue(state, params) {
var job = state.project.jobs[params.jobIndex];
job[params.field] = params.value;
Vue.set(state.project.jobs, params.jobIndex, job);
}
但它给了我相同的结果。
更新:根据要求,我创建了一个 jsFiddle 来显示我的问题
我会给出以下建议:
使用 v-bind:value="job.function
而不是 v-model="job.function"
因为您只需要单向绑定。这样您的代码更可预测。
将 v-key="job"
添加到您的 v-for="(job, index) in project.jobs"
元素以确保渲染正常工作。
前两行应该足够了,对象仍然是反应性的。
var job = state.project.jobs[params.jobIndex];
job[params.field] = params.value;
Vue.set(state.project.jobs, params.jobIndex, job);
PS:在我的 fiddle 中,@change
仅在我按下回车或离开输入时触发。
问题出在您的 addJob
操作中:
addJob: function (context) {
context.commit('addJob', state.defaultJob);
},
您每次添加新作业时都在引用 state.defaultJob
对象。这意味着 state.project.jobs
数组中的每一项都引用同一个对象。
将对象传递给 addJob
突变时,您应该创建该对象的副本:
addJob: function (context) {
context.commit('addJob', Object.assign({}, state.defaultJob));
},
或者,每次传入一个具有默认属性的新对象:
addJob: function (context) {
context.commit('addJob', {
function: '',
title: '',
description: '',
profiles: 1,
location_id: '',
category_id: '',
budget: '',
});
},
这里有一个 post 解释如何在 Javascript 中传递变量:Javascript by reference vs. by value
我正在开发一个使用 vuejs 和 vuex 的应用程序,它使用项目,每个项目都有一个或多个作业。
我可以添加、删除和更新作业。添加和删除工作完美,但更新不是。
vuex 开发工具中的状态:
我的HTML:
<div class="job-compact row" v-for="(job, index) in project.jobs">
<div class="col-md-6">
<div class="form-group" :class="{'has-error' : errors.has('jobs.' + index + '.function')}">
<input type="text" name="jobs[function][]" class="form-control" v-model="job.function" @change="updateJobValue(index, 'function', $event.target.value)"/>
</div>
</div>
<div class="col-md-4">
<div class="form-group" :class="{'has-error' : errors.has('jobs.' + index + '.profiles')}">
<input type="number" name="jobs[profiles][]" class="form-control" v-model="job.profiles" @change="updateJobValue(index, 'profiles', $event.target.value)"/>
</div>
</div>
<div class="col-md-2">
<button v-if="index == 0" class="btn btn-success btn-sm" @click="addJob"><i class="fa fa-plus"></i></button>
<button v-if="index > 0" class="btn btn-danger btn-sm" @click="deleteJob(index);"><i class="fa fa-minus"></i></button>
</div>
</div>
如您所见,我有一个 v-for
显示了我所有的工作。在我的作业中编辑值时,我使用 @change
事件来更新我的值。而且,在底部,我有两个按钮可以添加和删除作业行。
我的商店分为模块。主店长这样:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state = {};
const getters = {};
const mutations = {};
const actions = {};
//Separate Module States
import jobCreator from './modules/job-creator/store';
export default new Vuex.Store({
modules: {
jobCreator: jobCreator
},
state,
actions,
mutations,
getters
});
这个特定问题的模块存储:
import store from './../../store'
const state = {
project: {
title: null,
description: null,
jobs: []
},
defaultJob: {
function: '',
title: '',
description: '',
profiles: 1,
location_id: '',
category_id: '',
budget: '',
},
};
const getters = {}
const mutations = {
addJob(state, job) {
state.project.jobs.push(job);
},
deleteJob(state, index) {
state.project.jobs.splice(index, 1);
},
updateJobValue(state, params) {
Object.assign(state.project.jobs[params.jobIndex], {
[params.field]: params.value
});
}
};
const actions = {
addJob: function (context) {
context.commit('addJob', state.defaultJob);
},
deleteJob: function (context, index) {
context.commit('deleteJob', index);
},
updateJobValue: function (context, params) {
context.commit('updateJobValue', params);
},
};
const module = {
state,
getters,
mutations,
actions
};
export default module;
项目状态映射到我的 vue 实例的计算 属性:
computed: {
...mapState({
project: state => state.jobCreator.project,
}),
}
问题如下:在应用程序的图像中,您可以看到我在其中一个字段中输入了 "vin",但所有字段都在更新。
因此,所有 作业的所有 function
字段已更新为我的最后一个条目,而不仅仅是我想要的一个。
我做错了什么?
PS:
我还在我的突变函数中尝试了以下方法:
updateJobValue(state, params) {
var job = state.project.jobs[params.jobIndex];
job[params.field] = params.value;
Vue.set(state.project.jobs, params.jobIndex, job);
}
但它给了我相同的结果。
更新:根据要求,我创建了一个 jsFiddle 来显示我的问题
我会给出以下建议:
使用 v-bind:value="job.function
而不是 v-model="job.function"
因为您只需要单向绑定。这样您的代码更可预测。
将 v-key="job"
添加到您的 v-for="(job, index) in project.jobs"
元素以确保渲染正常工作。
前两行应该足够了,对象仍然是反应性的。
var job = state.project.jobs[params.jobIndex];
job[params.field] = params.value;
Vue.set(state.project.jobs, params.jobIndex, job);
PS:在我的 fiddle 中,@change
仅在我按下回车或离开输入时触发。
问题出在您的 addJob
操作中:
addJob: function (context) {
context.commit('addJob', state.defaultJob);
},
您每次添加新作业时都在引用 state.defaultJob
对象。这意味着 state.project.jobs
数组中的每一项都引用同一个对象。
将对象传递给 addJob
突变时,您应该创建该对象的副本:
addJob: function (context) {
context.commit('addJob', Object.assign({}, state.defaultJob));
},
或者,每次传入一个具有默认属性的新对象:
addJob: function (context) {
context.commit('addJob', {
function: '',
title: '',
description: '',
profiles: 1,
location_id: '',
category_id: '',
budget: '',
});
},
这里有一个 post 解释如何在 Javascript 中传递变量:Javascript by reference vs. by value