'Detect change to modelValue in Vue 3

Is there a way to detect change to modelValue in a custom component? I want to push the change to a wysiwyg editor.

I tried watching modelValue but emitting update for modelValue triggered that watch, which created circular data flow.

Code:

export default {
  props: ['modelValue'],
  watch: {
    modelValue (val) {
      this.editor.editor.loadHTML(val)
    }
  },
  mounted () {
    this.editor.editor.loadHTML(val)
    this.editor.addEventListener('trix-change', 
      (event) => this.$emit('update:modelValue', event.target.value))
  }
}
<TextEditor v-model="someHtml"></TextEditor>


Solution 1:[1]

In VueJS v3, the event name for custom v-model handling changed to 'update:modelValue'.

You can listen to these events like this: v-on:update:modelValue="handler"

For a more complete example, lets assume you have a Toggle component with these properties/methods:

...
props: {
        modelValue: Boolean,
},
data() {
    return {
        toggleState: false,
    };
},
methods: {
    toggle() {
        this.toggleState = !this.toggleState;
        this.$emit('update:modelValue', this.toggleState);
    }
}
...

You can use that Toggle component:

<Toggle v-model="someProperty" v-on:update:modelValue="myMethodForTheEvent"/>

As a side note, you could also v-model on a computed property with a setter; allowing you to internalise your state changes without using the update:modelValue event. In this example, it assumes you v-model="customProperty" on your custom Toggle component.

 computed: {
      customProperty: {
        get() {
          return this.internalProperty;
        },
        set(v) {
          this.internalProperty = v;
          console.log('This runs when the custom component 'updates' the v-model value.);
        },
      }
    },

Solution 2:[2]

I had the same problem and solved it using a slight tweak to the way you call the watch function:

setup(props) {
      watch(() => props.modelValue, (newValue) => {
            // do something
      })
}

Hence, the important thing is to add () => props.modelValue instead of just putting props.modelValue as the first argument of the watch function.

Solution 3:[3]

try that:

  watch: {
...
   modelValue: function(val) {
   console.log('!!! model value changed ', val);
 },
...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 developerjack
Solution 2
Solution 3 Gerhard