2

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.

2 Answers 2

4

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>
Sign up to request clarification or add additional context in comments.

Comments

0

From your code you are trying to listen to changes.. in v-model data.. // Your Vue components

<template>
    <input
        type="text"
        :id="name"
        :name="name"
        v-model="inputValue"
    >
</template>

<script>
    export default {
        props: ['name', 'value'],
        data: function () {
            return {
                inputValue: ""
            };
        },
        
    };
</script>

If You really want to listen for changes..

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

in your component file

<template>...</template>
<script>
    export default {
        props: ['name', 'value'],
        data: function () {
            return {
                inputValue: ""
            };
        },
        methods : {
    _keyUp : () => {// handle events here}

    };
</script>

check here for events on input here

To bind value from props..

get the props value, then assign it to 'inputValue' variable

it will reflect in tthe input element

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.