I'm working on an application using vuejs with vuex which uses projects, with each project having one or more jobs.
I can add, delete and update the jobs. The adding and deleting is working perfect, but the updating is not.
The state in the vuex dev tools:
My 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>
As you can see, I have a v-for
that is showing all my jobs. When editing a value inside my jobs, I use the @change
event to update my value. And, at the bottom, I have two buttons to add and remove a job row.
My stores are divided into modules. The main store looks like this:
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
});
The module store for this specific problem:
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;
The project state is mapped to a computed property of my vue instance:
computed: {
...mapState({
project: state => state.jobCreator.project,
}),
}
The problem is the following: In the image of the application, you can see that I entered "vin" in one of the fields, but all of the fields are updating.
So, all of the function
fields of all the jobs have been updated to my last entry, instead of only the one I want.
What am I doing wrong?
PS:
I also tried the following in my mutation function:
updateJobValue(state, params) {
var job = state.project.jobs[params.jobIndex];
job[params.field] = params.value;
Vue.set(state.project.jobs, params.jobIndex, job);
}
But it's giving me the same result.
UPDATE: As requested, I created a jsFiddle to show my problem