我有使用 v-model 指令的自定义输入组件,因此在输入时它会发出input
带有值的事件,而 v-mask 指令通过使当前输入值符合掩码并发出另一个具有修改值的input
事件来修改值。然而,这种方法会触发两个input
事件,并切换两个模型更改 - 一个是原始的,一个是蒙版的。我可以修改input
指令中的现有事件值吗?
const maskDirective = (() => {
const state = new Map();
return {
bind: (el) => {
const element = el instanceof HTMLInputElement ? el : el.querySelector('input');
const textMaskInput = createTextMaskInputElement({
inputElement: element,
mask: TextMasks.phoneNumber,
});
state.set('element', element);
state.set('input', textMaskInput);
},
update: () => {
const textMaskInput = state.get('input');
const element = state.get('element');
const {
state: { previousConformedValue },
} = textMaskInput;
textMaskInput.update();
// otherwise there's call stack size exceeded error, because it constantly fires input event from component, catches it, and fires event from directive
if (previousConformedValue !== element.value) {
const event = new Event('input', { bubbles: true });
element.dispatchEvent(event);
}
},
};
})();
<template>
<div
:class="{ 'is-disabled': disabled }"
class="c-base-input"
>
<input
ref="control"
v-bind="$attrs"
:class="{
'has-leading-icon': $slots['leading-icon'],
'has-trailing-icon': $slots['trailing-icon'],
'has-prepend-content': $slots['prepend'],
'has-append-content': $slots['append'],
'has-value': value !== null,
}"
:disabled="disabled"
:value="value"
:type="type"
class="c-base-input__control"
@input="onInput($event.target.value)"
>
<div
v-if="$slots['leading-icon']"
class="c-base-input__icon is-leading"
>
<slot name="leading-icon" />
</div>
<div
v-if="$slots['trailing-icon']"
class="c-base-input__icon is-trailing"
>
<slot name="trailing-icon" />
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: null,
},
disabled: {
type: Boolean,
default: false,
},
type: {
type: String,
default: 'text',
validator: value => ['text', 'tel', 'email', 'password'].indexOf(value) !== -1,
},
},
methods: {
onInput(value) {
if (value === '') {
this.$emit('input', null);
} else {
this.$emit('input', value);
}
},
},
};
</script>