So I have the following structure:
rules:[
0:{
subrule1:'',
subrule2:'',
subrule3:''
},
1:{
subrule1:'',
subrule2:'',
subrule3:''
}
]
and I loop through this structure like this:
<div v-for="(fields, index) in rules" :key="index">
<div>
<button @click.prevent="addMore()">
Add Rules
</button>
</div>
<div>
<button @click.prevent="deleteSubrule(index)">
Delete
</button>
</div>
<input
name="subrule1"
:value="getAdditionalIndex(index, 'subrule1')"
/>
<input
name="subrule2"
:value="getAdditionalIndex(index, 'subrule2')"
/>
<input
name="subrule3"
:value="getAdditionalIndex(index, 'subrule3')"
/>
</div>
here are the methods:
getAdditionalIndex(index, field) {
return this.rules[index][field];
},
addMore(){
const fields = {
subrule1:'',
subrule2:'',
subrule3:''
};
this.rules.push(fields)
},
deleteSubrule(index){
this.$delete(this.rules, index)
}
It won't bind and it throws error on deletion. I did some searching and most people say that deep watchers however their utilization of deep watchers are usually used with child components and not on v-for. Is there a way to utilize deep watchers in this way?
here's a runnable snippet:
<html>
<div id="app">
<div>
<button @click.prevent="addMore()">
Add Rules
</button>
</div>
<div>
<button @click.prevent="showStates()">
Show state results
</button>
</div>
<div v-for="(fields, index) in rules" :key="index">
<div>
<button @click.prevent="deleteSubrule(index)">
Delete
</button>
</div>
<input
name="subrule1"
:value="getAdditionalIndex(index, 'subrule1')"
@input="inputChange"
/>
<input
name="subrule2"
:value="getAdditionalIndex(index, 'subrule2')"
@input="inputChange"
/>
<input
name="subrule3"
:value="getAdditionalIndex(index, 'subrule3')"
@input="inputChange"
/>
</div>
</div>
<!-- Don't forget to include Vue from CDN! -->
<script src="https://unpkg.com/vue@2"></script>
<script>
new Vue({
el: '#app', //Tells Vue to render in HTML element with id "app"
data() {
return {
rules:[],
test:''
}
},
methods:{
addMore(){
const fields = {
subrule1:'',
subrule2:'',
subrule3:''
};
this.rules.push(fields)
},
deleteSubrule(index){
this.$delete(this.rules, index)
},
getAdditionalIndex(index, field) {
return this.rules[index][field];
},
inputChange(event){
return event.target.value
},
showStates(){
alert(JSON.stringify(this.rules))
}
}
});
</script>
</html>
CodePudding user response:
Instead of passing the term additional
, you should be passing the index
to the getAdditionalIndex
method
<html>
<div id="app">
<div>
<button @click.prevent="addMore()">
Add Rules
</button>
</div>
<div v-for="(fields, index) in rules" :key="index">
<div>
<button @click.prevent="deleteSubrule(index)">
Delete
</button>
</div>
<input
name="subrule1"
:value="getAdditionalIndex(index, 'subrule1')"
/>
<input
name="subrule2"
:value="getAdditionalIndex(index, 'subrule2')"
/>
<input
name="subrule3"
:value="getAdditionalIndex(index, 'subrule3')"
/>
</div>
</div>
<!-- Don't forget to include Vue from CDN! -->
<script src="https://unpkg.com/vue@2"></script>
<script>
new Vue({
el: '#app', //Tells Vue to render in HTML element with id "app"
data() {
return {
rules:[]
}
},
methods:{
addMore(){
const fields = {
subrule1:'',
subrule2:'',
subrule3:''
};
this.rules.push(fields)
},
deleteSubrule(index){
this.$delete(this.rules, index)
},
getAdditionalIndex(index, field) {
return this.rules[index][field];
},
}
});
</script>
</html>
But I would suggest you to use v-model in the input fields to prevent it from getting emptied as you add new rows, therefore you no longer need the getAdditionalIndex
method
<html>
<div id="app">
<div>
<button @click.prevent="addMore">
Add Rules
</button>
</div>
<div v-for="(fields, index) in rules" :key="index">
<div>
<button @click.prevent="deleteSubrule(index)">
Delete
</button>
</div>
<input
name="subrule1"
v-model="fields.subrule1"
/>
<input
name="subrule2"
v-model="fields.subrule2"
/>
<input
name="subrule3"
v-model="fields.subrule3"
/>
</div>
</div>
<!-- Don't forget to include Vue from CDN! -->
<script src="https://unpkg.com/vue@2"></script>
<script>
new Vue({
el: '#app', //Tells Vue to render in HTML element with id "app"
data() {
return {
rules:[]
}
},
methods:{
addMore(){
const fields = {
subrule1:'',
subrule2:'',
subrule3:''
};
this.rules.push(fields)
},
deleteSubrule(index){
this.$delete(this.rules, index)
},
}
});
</script>
</html>