Home > Mobile >  How can I modify an item from a v-for loop using a method?
How can I modify an item from a v-for loop using a method?

Time:12-15

In the following code, I am trying to update the child's age with the method coolstuff().

I know this can be done with inline vue code if I do v-on:input="child.age = 20", but how can I do this in the coolstuff() method?

<template>
    <div v-for="(person, personIndex) in people" :key="personIndex">
        <div v-for="(child, childIndex) in person.children" :key="childIndex">
            <input type="checkbox" v-on:input="coolstuff(child)">
        </div>
    </div>
</template>
export default defineComponent({
    data: () => ({
        people: [
            {
                name: "john",
                age: 50,
                children:[
                    { 
                        name: "sally",
                        age: 4
                    },
                    { 
                        name: "joe",
                        age: 5
                    }
                ]
            }           
        ]
    }),
    methods: {
        coolstuff (child) {
            // here I want to set the child.age = 20;
        }
    }   
});

I tried passing the variable "child" into the coolstuff() method, but I didnt know how to modify it...

CodePudding user response:

  1. Each record should have a unique id if you want to update it. So, it's recommended to use a unique identifier for both parent and child. For now, I am assuming the name is unique for parent and child, so pass only the names of parent and child in the method.
  2. Using the name, find the parent first and then the child and update its age.

In the template,

<input type="checkbox" v-on:input="coolstuff(person.name, child.name)">

In the JS method-

coolstuff(parent_name, child_name) {
    try {
      // Find the parent first
      let parent_index = this.people.findIndex(
        (item) => item.name == parent_name,
      );
      if (parent_index == -1) {
          throw "parent not found";
      }
      let parent = this.people[parent_index];

      // Now, find the requested child of parent
      let child_index = parent.children.findIndex(
        (item) => item.name == child_name,
      );
      if (child_index == -1) {
        throw "child not found";
      }
      this.$set(this.people[parent_index].children[child_index], "age", 20);
    } catch (error) {
      console.error(error);
    }
},

Here, I use Vue.set (this.$set) method to make the data reactive.

CodePudding user response:

You can simply achieve this requirement by just passing both personIndex and childIndex into the coolstuff method. By doing this, you can easily update the values of child objects.

Live Demo :

new Vue({
  el: '#app',
  data: {
    people: [
      {
        name: "john",
        age: 50,
        children:[
          { 
            name: "sally",
            age: 4
          },
          { 
            name: "joe",
            age: 5
          }
        ]
      }           
    ]
  },
  methods: {
    coolstuff(parentIndex, childIndex) {
      this.people[parentIndex].children[childIndex].age = 20;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="(person, personIndex) in people" :key="personIndex">
    <ul>
      <li>{{ person.name}}</li>
      <ul>
        <li v-for="(child, childIndex) in person.children" :key="childIndex">
          <input type="checkbox" v-on:input="coolstuff(personIndex, childIndex)">
          {{ child.name }} - {{ child.age }}
        </li>
      </ul>
    </ul>
  </div>
</div>

  • Related