Why is the Vue.js input value not updating?

22,570

You cannot mutate values between components like that.

Here is a sample snippet on how to properly pass values back and forth. You will need to use computed setter/getter. Added a button to change the value and reflect it back to the instance. It works for both directions.

<template>
    <div>
        <input type="text" :id="name" v-model="inputValue" />
        <button @click="inputValue='value2'">click</button>
    </div>
</template>
<script>
    export default {
        props: ['name', 'value'],
        computed: {
            inputValue: {
                get() {
                    return this.value;
                },
                set(val) {
                    this.$emit('updated', val);
                }
            }
        }
    }
</script>

Notice that the "@updated" event updates back the local variable with the updated value:

    <text-input :name="row.name" :value="row.value" @updated="item=>row.value=item"></text-input>
Share:
22,570

Related videos on Youtube

HartleySan
Author by

HartleySan

Updated on May 21, 2020

Comments

  • HartleySan
    HartleySan almost 4 years

    I have a Vue.js text-input component like the following:

    <template>
        <input
            type="text"
            :id="name"
            :name="name"
            v-model="inputValue"
        >
    </template>
    
    <script>
        export default {
            props: ['name', 'value'],
            data: function () {
                return {
                    inputValue: this.value
                };
            },
            watch: {
                inputValue: function () {
                    eventBus.$emit('inputChanged', {
                        type: 'text',
                        name: this.name,
                        value: this.inputValue
                    });
                }
            }
        };
    </script>
    

    And I am using that text-input in another component as follows:

    <ul>
        <li v-for="row in rows" :key="row.id">
            <text-input :name="row.name" :value="row.value">
            </text-input>
        </li>
    </ul>
    

    Then, within the JS of the component using text-input, I have code like the following for removing li rows:

    this.rows = this.rows.filter((row, i) => i !== idx);
    

    The filter method is properly removing the row that has an index of idx from the rows array, and in the parent component, I can confirm that the row is indeed gone, however, if I have, for example, two rows, the first with a value of 1 and the second with a value of 2, and then I delete the first row, even though the remaining row has a value of 2, I am still seeing 1 in the text input.

    Why? I don't understand why Vue.js is not updating the value of the text input, even though the value of value is clearly changing from 1 to 2, and I can confirm that in the parent component.

    Maybe I'm just not understanding how Vue.js and v-model work, but it seems like the value of the text input should update. Any advice/explanation would be greatly appreciated. Thank you.