自定义指令 输入框只能输入数字,也不可输入e+-等符号

 使用方法:v-number

//最大值最小值小数点位数
<el-input v-model.trim="scope.row.value"
    v-number="{ min: 0 ,precision: 0,max: 999 }"
    placeholder="非必填,0-999整数"
    size="small"></el-input>
</el-form-item>

<el-input v-number="{min:0,max:100}"
          step="1"
          v-model="warnSampleRatio">
</el-input>

//不填
<el-input v-number="{}"
          step="1"
          v-model="warnSampleRatio">
</el-input>

自定义指令写法:

/**
 * 设置输入框的值,触发input事件,改变v-model绑定的值
 * */
const setVal = (val, el, vNode) => {
    if (vNode.componentInstance) {
        // 如果是自定义组件就触发自定义组件的input事件
        vNode.componentInstance.$emit('input', val);
    } else {
        // 如果是原生组件就触发原生组件的input事件
        el.value = val;
        el.dispatchEvent(new Event('input'));
    }
};

/**
 * 参数检查
 * */
const optionCheck = (binding) => {
    // 范围值是否为数值
    if ((binding.value.max && typeof binding.value.max !== 'number') || (binding.value.min && typeof binding.value.min !== 'number')) {
        throw new Error('Range parameter must be numeric');
    }
    // 最大最小值存在的时候判断最大值与最小值是否相等
    if (binding.value.max === binding.value.min && typeof binding.value.max !== 'undefined' && typeof binding.value.min !== 'undefined') {
        throw new Error('The maximum and minimum values cannot be equal');
    }
};

/**
 * 判断是否为无效值
 * */
const isInvalidVal = (bindValue) => {
    return bindValue === null || isNaN(Number(bindValue)) || bindValue.toString().indexOf('.') === bindValue.length - 1 || bindValue.toString().indexOf('e') !== -1;
};

/**
 * 处理数值范围,如果输入值超过最大值或最小值,将会被自动设置为边界值
 * */
const dealRange = (inputValue, binding) => {
    let bindMax = typeof binding.value.max === 'undefined' ? Infinity : binding.value.max;
    let bindMin = typeof binding.value.min === 'undefined' ? -Infinity : binding.value.min;
    let result = inputValue;
    if (inputValue < bindMin) {
        result = bindMin;
    }
    if (inputValue > bindMax) {
        result = bindMax;
    }
    return result;
};

/**
 * 阻止输入
 * */
const preventInput = (event) => {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
};
export default {
    bind(el, binding, vNode) {
        optionCheck(binding);
        // 处理无效值
        let bindValue = vNode.data.model.value;
        if (isInvalidVal(bindValue)) {
            setVal(null, el, vNode);
            return;
        }

        // 处理数值范围
        let inputVal = dealRange(bindValue, binding);
        setVal(inputVal, el, vNode);
    },
    inserted(el, binding, vNode) {
        let content;
        // 按键按下=>只允许按照一定规则输入 数字/小数点/减号
        el.addEventListener('keypress', e => {
            const inputKey = String.fromCharCode(typeof e.charCode === 'number' ? e.charCode : e.keyCode);
            const inputReg = /\d|\.|-/;
            content = e.target.value;
            /**
             * 1.输入值不是数字、小数点、减号
             * 2.输入框为空或只有减号,不能输入小数点
             * 3.重复输入小数点
             * 4.输入框已有值,不能输入减号
             * 5.重复输入减号
             */
            // todo:已有值的时候,选中输入框的所有值输入减号‘-’,无法覆盖输入
            if (!inputReg.test(inputKey)) {
                preventInput(e);
            } else if (((content === '' || content === '-') && inputKey === '.')) {
                preventInput(e);
            } else if ((content.indexOf('.') !== -1 && inputKey === '.')) {
                preventInput(e);
            } else if ((content !== '' && inputKey === '-')) {
                preventInput(e);
            } else if ((content.indexOf('-') !== -1 && inputKey === '-')) {
                preventInput(e);
            }
        });
        // 按键弹起=>并限制最大最小
        el.addEventListener('keyup', e => {
            if (e.keyCode === 8) {
                return;
            }
            // 处理无效值
            let bindValue = e.target.value;
            if (bindValue === null) {
                setVal(null, el, vNode);
                return;
            }

            // 处理数值范围
            let inputVal = dealRange(bindValue, binding);
            setVal(inputVal, el, vNode);
        });
        // 失去焦点=>保留指定位小数
        el.addEventListener('focusout', e => { // 此处会在 el-input 的 @change 后执行
            // 处理无效值
            let bindValue = e.target.value;
            if (isInvalidVal(bindValue)) {
                setVal(null, el, vNode);
                return;
            }

            content = parseFloat(e.target.value);
            let contentStr = String(content);
            if (contentStr.indexOf('.') >= 0 && contentStr.split('.')[1].length > binding.value.precision) {
                let arg_precision = 0;// 默认保留至整数
                if (binding.value.precision) {
                    arg_precision = parseFloat(binding.value.precision);
                }
                content = content.toFixed(arg_precision);
            }
            setVal(content, el, vNode);
        });
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Embrace924

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值