Warm tip: This article is reproduced from stackoverflow.com, please click
frontend javascript loops recursion vue.js

VueJS Components inside a loop act as one

发布于 2020-04-18 09:37: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:

Result Screenshot

Questioner
Bry
Viewed
45
Tay 2020-02-05 10:18

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.