有一个很难绷的bug
import { Directive } from 'vue';
const getInput = (el: HTMLElement): HTMLInputElement | null => (el instanceof HTMLInputElement ? el : el.querySelector('input'));
let inputHandler = () => {};
/**
* 解决el-input 数字类型可以输入e + - 符号问题
*/
export const elInputNumber: Directive = {
mounted(el: HTMLElement, { arg, value }) {
const input: HTMLInputElement = <HTMLInputElement>getInput(el);
if (input) {
// 小数正则
const decimal: string = arg ? `(\\.\\d{0,${arg}})?` : '';
// 整数正则
const integer: string = value ? `(0|[1-9]\\d{0, ${value - 1}})` : '\\d*';
const regExp: RegExp = new RegExp(integer + decimal, 'g');
inputHandler = () => {
// 替换所有的非数字项
// 如果输入的数字不符合正则表达式,则替换为''
input.value =
input.value
.toString()
.trim()
.replace(/[^\d.]/g, '')
?.match?.(regExp)?.[0] ?? '';
};
// 在文本框输入的时候触发
input.addEventListener('input', inputHandler, true);
// input.addEventListener('blur', inputHandler, true);
}
},
unmounted(el: HTMLElement) {
// 解除绑定的时候去除事件
const input: HTMLInputElement = <HTMLInputElement>getInput(el);
input.removeEventListener('input', inputHandler, true);
}
};
这是一段自定义指令 只能输入数字 用在了el-input中
正常来看是可以拦住的,但是由于它会把非数字替换成空串,导致我在不小心输入中文时,如:你好
会在输入框依次出现 “nihao你好” 在中文出来之前 拼音已经出现在输入框了,导致原本输入的数字被替换为空
关键问题在于 输入中文后,之前绑定的参数似乎失去了绑定效果 上面是输入框的内容 下面是v-model绑定的数据
尝试过把input事件改成blur 也有其他bug出现如 “123你好” 失焦后输入框变成 123 但实际数据不变,可能是对于函数中的input来说 实际内容没变,导致数据没有更新
element自带的方法无法满足产品的要求,如不允许输入加减号等
给输入框@input方法可以解决 但每个input都给这个方法过于麻烦
希望可以满足只能输入数字的同时 不受以上bug影响
在Vue自定义指令中处理中文拼音输入对数字验证的影响确实是一个棘手的问题。拼音输入法在输入过程中会临时显示拼音字符,这些字符随后会被转换成实际的汉字。如果你的指令在拼音阶段就进行了验证和替换,那么就会导致你遇到的问题。
为了解决这个问题,你可以考虑以下几个方案:
延迟验证:
input
事件触发时立即进行验证和替换,而是设置一个短暂的延迟(例如100毫秒)。在延迟期间,如果用户继续输入,则取消之前的延迟并重新设置。只有当用户停止输入一段时间后,才进行验证和替换。setTimeout
和clearTimeout
来实现。使用
compositionstart
和compositionend
事件:compositionstart
时暂停验证,然后在compositionend
时进行验证和替换。结合Vue的
v-model
和watch
:input
事件中进行处理,你可以使用Vue的watch
来观察v-model
绑定的数据的变化。watch
回调中,你可以进行数字验证和替换。由于watch
是在数据变化后触发的,因此它不会受到拼音输入过程中的临时字符的影响。下面是一个使用
compositionstart
和compositionend
事件的修改后的指令示例:在这个示例中,我使用了
compositionstart
和compositionend
事件来跟踪拼音输入的状态,并在拼音输入完成后进行验证和替换。这样,拼音字符就不会干扰数字的验证了。同时,我也保留了input
事件处理器来处理普通的输入情况。