Reputation: 15
UPDATE Was able to make it work, but got one last problem. Updated code is here: VueJs not working on first click or first event
I've been trying to find out a way for the components inside a loop to not act as one.
I have a loop (3 divs), and inside the loop, I have 2 textboxes. But whenever I enter a value in any of them, the value is populated to everyone.
Can anyone help me separate those components?
I'm trying to make the parent div (1st loop) dynamic. So the children components (2nd loop) should be acting separately with their own grandparent components (textbox).
Here's my code:
<div id="app">
<div v-for="(ctr, c) in 3" :key="c">
<button @click="input_add">1st</button>
<div>
<div v-for="(input, act) in inputs" :key="act.id">
<input type="text" v-model="input.name">
<input type="text" v-model="input.time">
<button @click="input_remove(act)">Delete</button>
<button @click="input_add">Add row</button>
</div>
</div>
{{ inputs }}
</div>
</div>
const app = new Vue({
el: "#app",
data: {
inputs: [],
counter: 0,
},
methods: {
input_add() {
this.inputs.push({
id: this.counter + 1,
day: null,
name: null,
time: null,
})
this.counter += 1
},
input_remove(index) {
this.inputs.splice(index,1)
this.counter -= 1
}
}
});
Result:
Upvotes: 1
Views: 3279
Reputation: 670
as I mentioned in the comment, you should create a component for the iterated item.
parent component:
<div v-for="(item, index) in array" :key="index">
<child :item="item" />
</div>
Now you sent the item
as prop. Let's catch it in child.
child components:
<div>
<input type="text" v-model="input.name">
<input type="text" v-model="input.time">
<button @click="input_remove(act)">Delete</button>
<button @click="input_add">Add row</button>
</div>
{{ inputs }}
props: [item], // I am not sure you need it or not, BUT just showing how to do it.
data() {return { // your datas };},
methods: {
// your methods...
},
//and else...
Now each iterated item can control self only. I am hope it make sense now.
then build the buttons an input in child component. After that you can apply the events for just clicked item.
Upvotes: 1
Reputation: 3324
You should use Array of Objects
. Here's a codesandbox. This way everytime you add a new object to the array, a new index is created with a new name
and time
ready to be filled in.
<template>
<div id="app">
<img width="25%" src="./assets/logo.png">
<div v-for="item in basic" :key="item.id">
<button @click="addRow">Add row</button>
<input type="text" v-model="item.name">
<input type="text" v-model="item.time">
{{ item.name }} - {{ item.time }}
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
id: 1,
basic: [{ name: "", time: "" }]
};
},
methods: {
addRow() {
console.log("added");
this.id += 1;
this.basic.push({
name: "",
time: ""
});
}
}
};
</script>
Upvotes: 0