自定義指令 輸入框只能輸入數字,也不可輸入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);
        });
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章