Search code examples
javascriptvue.jsvuejs2componentsv-for

How to pass elements in a for loop to parent component?


Background I have a child component that loops through an array called "expenseButton" passed from my parent component. Within this for loop are elements that are getting updated. Specifically the "expense".

Child component

<form class="container">
      <div class="buttonList" v-for="(expense, index) in expenseButton" :key="index">
        <button type="button" @click="expenseButtonClick(expense)">{{expense.expensesKey}}</button>

        <input class="textInput" v-model.number="expense.subExpense" type="number" />

      </div>
</form>

<script>
export default {
  props: {
    expenseButton: Array,
  },
  methods: {
    expenseButtonClick(expense) {
      expense.expensesValue = expense.expensesValue - expense.subExpense;
    }
}
}
</script>

Problem I understand that $emit events can pass data to the parent. However, I am trying to figure the best way to send the updated elements of the array back to the parent component.

The Parent component data

<template>
<expense-button :expenseButton="expenseButton"></expense-button>

</template>

<script>
export default {
  components: {
    "expense-button": Expenses
  },
  data() {
    return {
      expenseButton: [    
{"expensesKey":"rent","expensesValue":null,"subExpense":""},
{"expensesKey":"movies","expensesValue":null,"subExpense":""},
{"expensesKey":"clothes","expensesValue":null,"subExpense":""}
],
    };
  }
}
</script>

Solution

  • I think you should use $emit. Child component:

    <form class="container">
          <div class="buttonList" v-for="(expense, index) in expenseButton" :key="index">
            <button type="button" @click="expenseButtonClick(expense)">{{expense.expensesKey}}</button>
    
            <input class="textInput" v-model.number="expense.subExpense" type="number" />
    
          </div>
    </form>
    
    <script>
    export default {
      props: {
        expenseButton: Array,
      },
      methods: {
        expenseButtonClick(expense) {
          expense.expensesValue = expense.expensesValue - expense.subExpense;
          this.$emit("expense-btn-clicked", expense)
        }
      }
    }
    </script>
    

    Parent component:

    <template>
      <expense-button :expenseButton="expenseButton" @expense-btn-clicked="btnClickedHandler"></expense-button>
    </template>
    
    <script>
    export default {
      components: {
        "expense-button": Expenses
      },
      data() {
        return {
          expenseButton: [    
            {"expensesKey":"rent","expensesValue":null,"subExpense":""},
            {"expensesKey":"movies","expensesValue":null,"subExpense":""},
            {"expensesKey":"clothes","expensesValue":null,"subExpense":""}
          ],
        }
      },
      methods: {
        btnClickedHandler(e) {
          console.log(e)
        }
      }
    }
    </script>