[Vuejs]-V-model in v-loop appears in text-field but nothing changes

0👍

The main reason nothing happens is because you don’t emit an event called input from the child component. v-model is just a shortcut for binding a value and emitting an event, thus implementing the two-way data binding with a single directive (see here).

However, you shouldn’t try to directly modify the prop in the children components. It is a highly recommended practice to not modify any value without the parent knowing about it.

In general, whenever you need to iterate over values, rather than making a component that handles the whole array, it is often better to have a component handle a single value out of the array. The way you named the child component, AddProduct, suggests that you also wanted to it like this in a way. So I would suggest the following modifications.

Nested component

 <template>
  <transition name="fade">
    <div class="add-box">
      <div class="input--form">
        <label>{{ input.label }}: </label>
        <input :type="input.type" :value="input.model" @input="onInput" />
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  props: {
    input: Object,
  },
  methods: {
    onInput(event) {
      this.$emit("input", {
        ...this.input,
        model: event.target.value,
      });
    },
  },
};
</script>

Parent component

<template>
  <div id="app">
    <add-product
      v-for="(input, index) in inputs"
      :key="input.id"
      :input="input"
      v-model="inputs[index]"
    ></add-product>
  </div>
</template>

<script>
import AddProduct from "./AddProduct";

export default {
  name: "App",
  components: {
    AddProduct,
  },
  data() {
    return {
      inputs: [
        { id: "1", label: "name", type: "text", model: "name" },
        { id: "2", label: "description", type: "text", model: "desc" },
        { id: "3", label: "price", type: "text", model: "price" },
        { id: "4", label: "size", type: "text", model: "size" },
        { id: "5", label: "stock", type: "text", model: "stock" },
      ],
    };
  },
};
</script>

The child component doesn’t modify the prop, only emits the input object with updated value. Since the name of the event is input and the prop’s name is value, v-model will work. In the parent the inputs array is iterated and for each input the v-model directive is attached. Find a live demo here

Leave a comment