Skip to content
This repository was archived by the owner on Sep 4, 2024. It is now read-only.

Commit dfe6590

Browse files
committed
* now directive will compare previous mask result with the current one if the binding value is a function when triggering update * `input` event will not fire if calculated masked value is the same as the value of the input
1 parent 5f1490b commit dfe6590

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/__tests__/index.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,17 @@ describe('directive usage', () => {
243243
await wrapper.vm.$nextTick();
244244
expect(wrapper.vm.$el.value).toBe('19:32');
245245
});
246+
247+
it('should not trigger input events if resolved mask is the same as previous one', async () => {
248+
const wrapper = mountWithMask({
249+
props: { triggerUpdate: { required: false } },
250+
data: () => ({ mask: () => [/\d/, /\d/], value: null }),
251+
template: '<input v-mask="mask" v-model="value" v-on:input="$emit(\'input\', $event)" />',
252+
});
253+
254+
await wrapper.setProps({ triggerUpdate: true });
255+
expect(wrapper.emitted().input).toBeFalsy();
256+
});
246257
});
247258

248259
describe('filter usage', () => {

src/directive.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ function triggerInputUpdate(el) {
2020
trigger(el, 'input');
2121
}
2222

23+
function updateElementWithMaskedValue(el, maskedValue) {
24+
if (maskedValue === el.value) {
25+
return;
26+
}
27+
28+
el.value = maskedValue;
29+
triggerInputUpdate(el);
30+
}
31+
2332
/**
2433
* Event handler
2534
* @param {HTMLInputElement} el
@@ -35,8 +44,8 @@ function updateValue(el, force = false) {
3544

3645
if ((force || isUpdateNeeded) && mask) {
3746
const { conformedValue } = conformToMask(value, mask, { guide: false });
38-
el.value = conformedValue;
39-
triggerInputUpdate(el);
47+
48+
updateElementWithMaskedValue(el, conformedValue);
4049
}
4150

4251
options.partiallyUpdate(el, { previousValue: value });
@@ -95,6 +104,22 @@ function maskToString(mask) {
95104
return filteredMaskArray.toString();
96105
}
97106

107+
/**
108+
* Check if previous mask has been different than current one
109+
* @param {String|Array.<String|RegExp>} mask
110+
*/
111+
function hasMaskFromBindingChanged(el, oldValue, currentValue) {
112+
const previousMask = isFunction(oldValue)
113+
? maskToString(oldValue(options.get(el).previousValue))
114+
: maskToString(oldValue);
115+
116+
const currentMask = isFunction(currentValue)
117+
? maskToString(currentValue(el.value))
118+
: maskToString(currentValue);
119+
120+
return previousMask !== currentMask;
121+
}
122+
98123
/**
99124
* Create the Vue directive
100125
* @param {Object} directiveOptions
@@ -139,8 +164,7 @@ export function createDirective(directiveOptions = {}) {
139164
componentUpdated(el, { value, oldValue }) {
140165
el = queryInputElementInside(el);
141166

142-
const isMaskChanged = isFunction(value)
143-
|| maskToString(oldValue) !== maskToString(value);
167+
const isMaskChanged = hasMaskFromBindingChanged(el, oldValue, value);
144168

145169
if (isMaskChanged) {
146170
updateMask(el, value, instanceMaskReplacers);

0 commit comments

Comments
 (0)