Vue: Force v-model to update its value?

Created on 9 Aug 2015  Â·  10Comments  Â·  Source: vuejs/vue

Sometimes you have a textfield set up as v-model which can change due to an external javascript process(like a datepicker).
In those cases, the 2-way-binding of the v-model doesn't gets fired. Is there a way of forcing Vue to fetch the actual value of his binding(In case it had changed and Vue didn't notice).

Most helpful comment

If you set properties on an element imperatively, you need to dispatch a native event to force bound data to update:

const event = new Event('input')
vm.$refs.child.value = 'something'
vm.$refs.child.dispatchEvent(event)

Different elements need different event types:

| element |event type| property|
| ------------- |-----|-----|
| <input[type="checkbox"]>| change |checked |
| <input[type="radio"]>| change |checked |
| <input>| input |value |
|<textarea> | input|value |
| <option> | change|selected |

All 10 comments

@patrick-hertling I don't think this should be solved by vue, but rather by the external library you are using. With jQuery-stuff you should $(element).trigger('change') or $(element).trigger('input'), depending on your needs. In general case, custom two-way directives are the solution you might be looking for.

Thank you. I think I will use a directive.

How do we use two way directives ? i tried, using @change="(value) => checked = value" to detect change and set the value, but it is not working for me

I'm having this issue while testing a Vue controlled form with Selenium. When running the Selenium tests Vue doesn't catch the changes. I wonder if there is a method to refresh the whole dataset from the view.

@markskayff i found this way:
for text inputs, dispatch native input event, for other types use native change events to trigger v model update

I am facing the same issue.
is there any working solution?

If you set properties on an element imperatively, you need to dispatch a native event to force bound data to update:

const event = new Event('input')
vm.$refs.child.value = 'something'
vm.$refs.child.dispatchEvent(event)

Different elements need different event types:

| element |event type| property|
| ------------- |-----|-----|
| <input[type="checkbox"]>| change |checked |
| <input[type="radio"]>| change |checked |
| <input>| input |value |
|<textarea> | input|value |
| <option> | change|selected |

@eddyerburgh, I tried your solution but it's not working in my scenario.
Pls see this completed details about my scenario - https://nuxtjs.cmty.io/nuxt/nuxt.js/issues/c7037

i am getting this error-
_Index.vue?4344:148 Uncaught TypeError: this.cartForm.item[n].dispatchEvent is not a function_

@eddyerburgh Thank you, your way is a good solution to Input element, but it seems not working with the image element.

I got some images they bind to different data, but they also bind to the same function. And I do not want to bind value using if-else branch。

<img :src="d.A" @click="fn" />
...
<img :src="d.Z" @click="fn" />

fn(e) {
    //  this is it should be
    e.target.src = 'some-address'

    //  this is just not good
    if(xxxx) d.A = 'xxxx'
    ...
    else d.Z = 'xxxx'
}

Wrap the native textField component in a custom component, add a watcher for the changing property, in the watcher call the forceUpdate() function to re-render the component.

TS texample:

    @Watch('value')
    private watchValue(val: string, oldVal: string) {
        this.time = val
        this.$forceUpdate()
    }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

gkiely picture gkiely  Â·  3Comments

julianxhokaxhiu picture julianxhokaxhiu  Â·  3Comments

loki0609 picture loki0609  Â·  3Comments

fergaldoyle picture fergaldoyle  Â·  3Comments

lmnsg picture lmnsg  Â·  3Comments