0
点赞
收藏
分享

微信扫一扫

vue2自定义指令实现 el-input 输入数字,小数点两位 最高10位,不满足则截取符合规则的值作为新值

步骤 1:创建自定义指令

// 处理输入值,确保符合规则
function processValue(value) {
// 过滤非数字和小数点
let filtered = value.replace(/[^\d.]/g, '');
const firstDotIndex = filtered.indexOf('.');

// 处理多个小数点,保留第一个
if (firstDotIndex !== -1) {
filtered = filtered.substring(0, firstDotIndex + 1) + filtered.substring(firstDotIndex + 1).replace(/\./g, '');
}

// 分割整数和小数部分
const parts = filtered.split('.');
let integerPart = (parts[0] || '').slice(0, 10); // 整数最多10位
let decimalPart = parts.length > 1 ? parts[1].slice(0, 2) : ''; // 小数最多两位

// 处理以小数点开头的情况(如 .98 → 0.98)
if (filtered.startsWith('.') && integerPart === '') {
integerPart = '0';
}

// 组合结果
let newValue = integerPart;
if (parts.length > 1 || filtered.endsWith('.')) {
newValue += '.' + decimalPart;
}

return newValue;
}

// 注册自定义指令
Vue.directive('number', {
bind(el, binding, vnode) {
const input = el.querySelector('input.el-input__inner');
if (!input) return;

let composing = false; // 标记是否在输入法组合中

const handler = (e) => {
if (composing) return;
const newVal = processValue(e.target.value);
if (e.target.value !== newVal) {
e.target.value = newVal;
input.dispatchEvent(new Event('input', { bubbles: true })); // 触发更新
}
};

// 输入法处理
const compositionStart = () => { composing = true; };
const compositionEnd = (e) => {
composing = false;
handler(e);
};

input.addEventListener('compositionstart', compositionStart);
input.addEventListener('compositionend', compositionEnd);
input.addEventListener('input', handler);

// 保存处理函数以便解绑
el._numberHandlers = { compositionStart, compositionEnd, handler };

// 初始值处理
const initialValue = vnode.componentInstance?.value ?? input.value;
const processedVal = processValue(initialValue);
if (initialValue !== processedVal) {
vnode.componentInstance?.$emit('input', processedVal);
}
},

update(el, binding, vnode) {
const input = el.querySelector('input.el-input__inner');
const currentValue = vnode.componentInstance?.value ?? input?.value;
if (currentValue === undefined) return;

const newVal = processValue(currentValue);
if (currentValue !== newVal) {
vnode.componentInstance?.$emit('input', newVal);
}
},

unbind(el) {
const input = el.querySelector('input.el-input__inner');
if (input && el._numberHandlers) {
const { compositionStart, compositionEnd, handler } = el._numberHandlers;
input.removeEventListener('compositionstart', compositionStart);
input.removeEventListener('compositionend', compositionEnd);
input.removeEventListener('input', handler);
delete el._numberHandlers;
}
}
});

步骤 2:在组件中使用指令

<template>
<el-input v-number v-model=inputValue></el-input>
</template>

<script>
export default {
data() {
return {
inputValue: ''
};
}
};
</script>

功能说明

  1. 过滤非数字字符:只允许输入数字和小数点。
  2. 限制小数点数量:确保只保留第一个小数点,后续的自动移除。
  3. 整数部分限制:最多输入 10 位整数,超长部分截断。
  4. 小数部分限制:最多输入 2 位小数,超长部分截断。
  5. 输入法兼容:处理中文输入法状态,避免中途过滤。
  6. 初始值处理:当初始值不符合规则时自动修正。
  7. 实时更新:通过触发 input 事件确保 v-model 同步更新。

注意事项

  • 该指令依赖于 Element UI 的 el-input 结构,确保内部输入框的类名为 el-input__inner
  • 处理后的值会覆盖用户输入,确保始终符合规则。
  • 支持输入法组合输入(如中文拼音),提升用户体验。
举报

相关推荐

0 条评论