0👍
I agree with Bert that you should not be trying to adjust the Vue object through directives. On the other hand, you should be able to set up an event handler. In your event handler, event.target.value
does not have the updated value. This appears to be related to the fact that you also attached an input handler via Vue. When I removed @input="setDirty"
, that got fixed. So I think the first lesson is: mixing event listeners can cause conflicts.
That aside, you can actually wind up with a facsimile of v-model
:
new Vue({
el: '#app',
data() {
return {
value: 'initial',
eventListenerCalled: false
}
},
directives: {
rinput: {
bind: function(el, bind, vnode) {
el.value = bind.value;
el.addEventListener('input', function(event) {
vnode.context.eventListenerCalled = true;
vnode.context.value = event.target.value; //changing data.value
});
}
}
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<input v-rinput="value">
<p>{{ value }}</p>
<div v-if="eventListenerCalled"> Event Listener Called </div>
</div>
Here’s a minimal snippet to illustrate the bug. If the Vue-style event handler modifies data, event.target.value
is wrong in the JS-style event handler (which is called after the Vue-style handler).
new Vue({
el: '#app',
data: {
value: 'initial',
isDirty: false
},
directives: {
rinput: {
bind: function(el, bind, vnode) {
el.addEventListener('input', function(event) {
console.log("Listener called", event.target.value);
});
}
}
},
methods: {
setDirty(event) {
console.log("Dirty called", event.target.value);
this.isDirty = !this.isDirty; // Without this, the listener works fine
}
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<input @input="setDirty" v-rinput="value" :value="value">
<p>{{ value }}</p>
<div v-if="isDirty"> Dirty function called </div>
</div>
Source:stackexchange.com