Bootstrap

el-input-number的精度问题

前言

el-input-number 饿了么的数字输入框组件,在项目中听常用的。而这个组件比较常用的属性就是精度设置,给组件添加属性precision
其实吧,之前一直没怎么研究,保留几位小数就直接填几就好了,比如保留两位小数,那就填2。但是最近遇到了个需求,需要根据设置好的舍入类型进行舍入,还是以保留两位小数为例:

  • 舍位,不论第三位小数是几都舍弃
  • 进位,不论第三位小数是几都往前进一位
  • 四舍五入,第三位小数,按照四舍五入来决定是进位还是舍位

在这里插入图片描述
每一个重量单位都有相应的精度以及舍入类型。根据选择的重量单位对净重进行处理。
如果设置了precision属性,使用时需要删除。

这里考虑的是通过指令来处理该问题,方便后期的修改、扩展等

完整代码

import { ObjectDirective } from 'vue'

const handleInputNumber = (el, binding) => {
    const inputEl = el.getElementsByClassName('el-input__inner')[0]
    /**
     * value:当前值
     * precision:当前的精度
     * type,舍入类型,0(四舍五入),1(舍位),2(进位)
     * isHandle,是否处理
     */
    const { value, precision, type, isHandle } = binding.value

    //console.log(precision, type, isHandle)

    let newValue = undefined
    if (isHandle && (value != null || value != undefined)) {
        const base = Math.pow(10, precision)
        // 要先对值进行截取,以保留两位小数进位为例,1.2301,应该为1.23,而下面的处理会变成1.24
        newValue = `${value || 0}`
        // 判断是否是小数
        if (newValue.indexOf('.') != -1) {
            // 进行截取
            newValue = Number(newValue.substr(0, newValue.indexOf('.') + precision + 2))
        } else {
            // 如果是整数,整数无法执行toFixed
            newValue = Number(newValue)
        }
        if (type == 0) {
            // 四舍五入
            newValue = Number(newValue.toFixed(precision))
        } else if (type == 1) {
            //舍位
            newValue = Number(Math.floor(newValue * base) / base)
        } else if (type == 2) {
            //进位
            newValue = Number(Math.ceil(newValue * base) / base)
        }
        // console.log('新值:', newValue)
        // 最后直接将字符串的值进行赋值,不能使用parseFloat或Number进行转换,转换后的值无法补零
        //判断当前输入框是否是激活状态,激活状态等失去焦点后再赋值
        if (inputEl.activeElement) {
            // 这里要等输入框失去焦点后再进行赋值
            inputEl.addEventListener('blur', event => {
                event.target.value = newValue.toFixed(precision)
            })
        } else {
            inputEl.value = newValue.toFixed(precision)
        }
    }
}
const btInput: ObjectDirective = {
    mounted(el, binding) {
        handleInputNumber(el, binding)
    },
    updated(el, binding) {
        handleInputNumber(el, binding)
    },
}
export default btInput
;