1
votes

I am trying to set up a component which passes a computed property back to the parent via a v-model.
This is explained, using the direct value of an input rather than a computed property, in the docs at https://vuejs.org/v2/guide/components.html#_carbonads_projs

So far, I've got the basic functionality working as per the docs, but I want to now set the value of the input which emits the event / sends data to the parent to be that of a computed property. I can set the value to the computed property this no problem, but the event is never triggered (looking in vue dev tools)

The below works, emitting an event with whatever was typed in the input, and updating the relevant data on the parent

<input type="text" v-bind:value="value" v-on:change="$emit('input', $event.target.value)">

//parent call to component
<time-picker v-model="parentData"></time-picker>

If I set up like this however, and cause a change in the computedProp by changing some other input, no event is fired, though I see the value of the input change. (I've also tried calling a custom method instead of emitting the event, but the method doesn't run either)

<input type="text" v-bind:value="computedProp" v-on:change="$emit('input', $event.target.computedProp)">

I've also tried using v-model rather than v-bind:value, but still no event

<input type="text" v-model="computedProp" v-on:change="$emit('input', $event.target.value)">

However if I type directly in the input which has v-bind:value="computedProp", an event is emitted (albeit without the correct data)

This makes me suspect that @input and @change aren't firing when the computed property updates, even though this causes a change in the value of said input. Is there an alternative to @change or @input that I should be using to monitor a computed property?

Ideally I don't want to have to emit an event in the child and manually catch it and assign the data in the parent, as the component will be used multiple times in the same parent and it will be far more convenient to use v-model directly on each instance.

Alternatively, am I barking totally up the wrong tree, and is there another / better way to pass a computed property to the v-model specified when the component is called?

Many thanks :)

1

1 Answers

4
votes

input and change event listener is emitted by user when in input is being typed on. Changing the value programmatically won't trigger the event.

There is a way to trigger the event programmatically. But I would like to suggest you to use Vue watcher instead. It's much more cleaner and easier.

It's as simple as this

  watch: {
    computedProp(newValue) {
      this.$emit("input", newValue);
    }
  }

What this does is that, Vue will watch the value of computedProp so that everytime its value changes, this.$emit("input", newValue); will be executed. Which is what you want.