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>