Search code examples
javascriptvue.jsv-forv-model

Vue updates all input fields in v-for loop instead of only one


So i'm breaking my head over this one for a couple of hours already, and haven't had success Googling.

I have a v-for loop that iterates over an array of objects. In that v-for loop I render input fields with the name and price of that option. The problem I'm encountering is that if I update one field, they al get updated. It seems like they share the exact same v-model, while that's not true. Here is my HTML

            <div
                v-for="(option, index) in options"
                :key="index"
                class="row w-full mt-2"
            >
                <text-input
                    v-model="option.name"
                    label="Optie"
                    class="col w-1/2"
                />
                <text-input
                    v-model="option.price"
                    label="Prijs"
                    prefix="+ €"
                    class="col w-1/4"
                />
            </div>

        <button
            class="text-gray-700 flex items-center mt-3"
            @click.prevent="addNewOption"
        >
            <icon
                icon="icons/plus-circle"
                class="w-4 h-4 mr-2 icon icon-light"
            /> Add options
        </button>

My js

data() {
    return {
       newOption: {
            name: null,
            price: null,
        },

        options: [],
    };
},
methods: {
      addNewOption() {
        this.options.push(this.newOption);
    },
},

Can you guys spot what I'm doing wrong here?

Thanks in advance!


Solution

  • I guess you are adding the same this.newOption object over and over. So if you change one, you change them all because they are the same object. So use a spread operator or better yet, just remove newOptions from the component's state. It does not look like this needs to be reactive state.

    data() {
        return {
            options: [],
        };
    },
    methods: {
        addNewOption() {
            this.options.push({
                name: null,
                price: null,
            });
        },
    },