背景 arco的inputNumber
场景: 指定precision,但是输入的数字会被四舍五入,0.99999实际输入为1
版本:
arco.bytedance.net/react/compo…
期望:精度5位,不四舍五入,超出不许输入
- 第一个方案: 比自己想要的多一位然后再用replace(0,-1)
precision:6, // 直接写5可以实现控制精度,但是会四舍五入(内核使用toFixed)
formatter: (value,{userTyping,input}) => userTyping
? input
: value
? value.slice(0,-1) //因为precision会自动补0,所以只要顺势截掉一位就可以了
: value,
parser: value => value,
通过 formatter 中的 userTyping 参数,判断是否正在输入,可以延迟显示 formatter 后的值,但是使用 输入0.9999999的时候会转成1(Js 浮点数)
- 第二个方案: 所以只能单独写一个函数来实现
// 小数位超出截取 不足补0
export const formatterNumber = (num, precision, blur = false) => {
const value = String(num).split('.');
let float = value[1];
if (value.length === 2 && float === '') return num;
if (float) {
if (float.length < precision) {
blur && (float += '0'.repeat(precision - float.length));
} else {
float = float.slice(0, precision);
}
} else {
blur && (float = '0'.repeat(precision));
}
return float ? `${value[0]}.${float}` : `${value[0]}`;
};
// 配置
formatter: value => formatterNumber(value, 5),
parser: value => value,
- 第三个方案[ finally]: 发现input参数是原生输入的数字
precision:5, // 直接写5可以实现控制精度,但是会四舍五入(内核使用toFixed)
formatter: (value,{userTyping,input}) => {
if(userTyping){
return input
}
if(input){
const float = input.split('.')
if(_.isEmpty(float[1])) return value
return `${input}000000`.slice(0,value.length)
}
return value
},
parser: value => value,
这个可以满足,然后把formatter抽出来使用,而且代码很好看~
调研中发现antd也有这个问题
而且有个衍生case:github.com/ant-design/…