When I use custom directive to change component\'s value, there is not effect:
Just create a input event using Event function.
var event = new Event("input", { bubbles: true });
then modify the value and then dispatch the event, it will update the v-model value
el.dispatchEvent(event);
Vue.directive('maxchars', {
update(el, binding, vnode) {
var event = new Event("input", { bubbles: true });
let maxChars = binding.value;
if (el.value.length > maxChars) {
el.value = e.value.substr(0, maxChars);
el.dispatchEvent(event);
}
}
});
hope it will helpful.
First:
v-model
, the value of the textarea
will be whatever is in the v-model
's variable (in this case, the variable content
). This means that the initial value of the DOM is ignored.content
in data()
.Second:
.value
directly. v-model
actually watches for input
✱ events from the DOM element.
change
event, or othervalue
, Vue will simple override it back (to whatever is in content
) next time an update happens.After changing the .value
, trigger input
event. Vue will pick the event up and update the v-model
variable from the current .value
before it overrides it.
Demo:
Vue.directive('maxchars', {
bind(el, binding, vnode) {
let maxChars = binding.value;
let handler = function(e) {
if (e.target.value.length > maxChars) {
e.target.value = e.target.value.substr(0, maxChars);
vnode.elm.dispatchEvent(new CustomEvent('input')); // added this
}
}
el.addEventListener('input', handler);
}
});
let app = new Vue({
el: '#app',
data() {
return {
content: 'tell me something',
totalCount: 140
}
}
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id='app'>
<div>
<div class='content'>
<textarea v-model='content' v-maxchars='18'></textarea>
</div>
<pre>
content: {{ content }}
Max chars is 18, current is {{ content.length }}.
</pre>
</div>
</div>