JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.css">
<div id="create-container">
<div class="job-compact row" v-for="(job, index) in project.jobs">
<div class="col-md-6">
<div class="form-group">
<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">
<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">add</button>
<button v-if="index > 0" class="btn btn-danger btn-sm" @click="deleteJob(index);">remove</button>
</div>
</div>
</div>
JavaScript
const state = {
project: {
title: null,
description: null,
jobs: []
},
defaultJob: {
function: '',
title: '',
description: '',
profiles: 1,
location_id: '',
category_id: '',
budget: '',
}
};
const mutations = {
addJob(state, job) {
state.project.jobs.push(job);
},
deleteJob(state, index) {
state.project.jobs.splice(index, 1);
},
updateJobValue(state, params) {
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 jobCreator = {
state,
mutations,
actions
};
const store = new Vuex.Store({
modules: {
jobCreator: jobCreator
},
});
// Vue
const vm = new Vue({
el: '#create-container',
store,
computed: Vuex.mapState({
project: state => state.jobCreator.project,
}),
created() {
store.dispatch('addJob');
},
methods: {
addJob: function()
{
this.$store.dispatch('addJob');
},
deleteJob: function (index) {
this.$store.dispatch('deleteJob', index);
},
updateJobValue(jobIndex, field, value)
{
this.$store.dispatch('updateJobValue', {
'jobIndex': jobIndex,
'field': field,
'value': value
});
}
}
})