前言
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