カスタムコマンド入力ボックスは数字だけ入力できます.e+-などの記号も入力できません.

5170 ワード

使用方法:v-number
//           






//  


カスタムコマンドの書き方:
/**
 *        ,  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);
        });
    }
};