1

I feel like I am about to go down a path of extreme inefficiency when trying to keep data correctly mapped between a Parent and Child component.

If I have a simple Child Vue element like below

common/InputText.vue

<template>
    <input v-bind:id="name" v-bind:value="value" v-on:input="changed($event, $event.target.value)">
</template>

<script>
    props: ['name', 'value'],
    methods: {
        changed(event, value) { this.$emit('emitChanged', event, value); }
    }
</script>

If I have a Parent Vue element like below, it is binding data to the Child elements. The problem is that it seems to be only binding from the Parent to the Child, the Parent data is not updating

Parent.vue

<input-text name="field01" v-bind:value="field01" @emitChanged="changed"></input-text>
<input-text name="field02" v-bind:value="field02" @emitChanged="changed"></input-text>

<script>
    import inputText from "./common/InputText.vue";
    export default {
        data() {
            return() {
                field01: '',
                field02: ''
            }
        },
        components: {
            input-text: inputText
        },
        changed(event, newValue) {
            console.log(newValue);
        }
    }
</script>

I am able to update the Parent data with whatever the data the Child returns by changing the changed method to the below

changed(event, newValue) {
    console.log(newValue);
    if( event.target.id == 'field01' ) {
        this.field01 = newValue;
    }
    if( event.target.id == 'field02' ) {
        this.field02 = newValue;
    }
}

This feels like a hack though and will become unmanageable should there be many input fields. What is the correct way to reupdate the Parent data?

6
  • 1
    This sounds like a perfect time to implement Vuex ;) Commented Jan 25, 2021 at 12:58
  • 1
    A state management framework based on the flux pattern. I highly recommend learning about it and it will help you to avoid many of these types of rabbit holes you were finding yourself going down vuex.vuejs.org <-- give the video on that page a watch, it's only 5 minutes Commented Jan 25, 2021 at 13:08
  • 1
    @maxshuty please exxplain why vuex is required in solution of this problem Commented Jan 25, 2021 at 13:10
  • 1
    @ashwinbande I never said it was a required solution. However, if you're having issues managing state and you're not using Vuex, then it may be time to start looking at it. Sure it can add some extra boilerplate, but you can go down many rabbit holes once you start passing props down components several layers deep and using Vuex solves all of that mess. Unless the app is an extremely trivial app or a prototype then using Vuex can help the OP not only learn the flux pattern, but also help prevent these sorts of issues all together in the first place. Commented Jan 25, 2021 at 13:54
  • 1
    Even though it doesn't help for this case it's always nice to hear other options, thanks a bunch @maxshuty Commented Jan 25, 2021 at 13:58

1 Answer 1

1

This is why the v-model is useful, you can change your code in following way to overcome your problem without using v-model. but I would recommend try to implement v-model way.

<template>
    <input v-bind:id="name" v-bind:value="value" v-on:input="changed($event, $event.target.value)">
</template>

<script>
    props: ['name', 'value'],
    methods: {
        changed(event) { this.$emit('emitChanged', event); }
    }
</script>
<input-text name="field01" v-bind:value="field01" @emitChanged="changed($event, 'field01')"></input-text>
<input-text name="field02" v-bind:value="field02" @emitChanged="changed($event, 'field02'"></input-text>

<script>
    import inputText from "./common/InputText.vue";
    export default {
        data() {
            return() {
                field01: '',
                field02: ''
            }
        },
        components: {
            input-text: inputText
        },
        changed(event, field) {
            this[field] = event.target.value
        }
    }
</script>
Sign up to request clarification or add additional context in comments.

4 Comments

Pardon my stupidity but where is the field parameter coming from in the changed method?
changed($event, 'field01')
In @emitChanged="changed($event, 'field01')" of input-text.
That's amazing, is it possible to also include the newValue field as well? I'm unfamiliar with the syntax for including variables manually in an emit event

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.