/**
*
* @param value 当前输入值
* @param precision 保留小数位数
* @param min 最小值,可控制正负
* @param max 最大值
* @returns number 处理后的值
*/
export const validateInput = (
value,
precision = 0,
min?: number,
max?: number,
) => {
const _IntegerNumber = () => {
let str2;
let reg;
if (Math.abs(precision) > 0) {
if (min >= 0) {
reg = /[^\d\.]/g;
} else {
reg = /[^-?\d\.]/g;
}
} else {
if (min >= 0) {
reg = /[^\d]/g;
} else {
reg = /[^-?\d]/g;
}
}
str2 = value.replace(reg, "");
const arr_ = str2.split("-");
let str: any;
if (str2.indexOf("-") > -1) {
if (arr_.length === 1) {
str = arr_[0];
} else if (arr_.length === 2) {
str = !arr_[1] ? arr_[0] || "-" : "-" + _resolvePoint(arr_[1]);
} else if (arr_.length === 3) {
str = "-" + value.replaceAll("-", "");
}
} else {
str = str2;
}
let valueTemp = str;
if (str && str.length > 1 && str[0] === "0") {
// message.error('请输入合法数字')
valueTemp = parseFloat(str);
}
if (str.indexOf(".") > -1) {
const arr = str.split(".");
console.log(
parseFloat(arr[0]),
parseFloat(arr[0]) === parseFloat(arr[0]),
);
if (arr[1]) {
valueTemp =
parseFloat(arr[0]) === parseFloat(arr[0])
? parseFloat(arr[0]).toString() +
"." +
arr[1].substr(0, Math.abs(precision))
: parseFloat(arr[1]);
} else {
valueTemp = arr[0] + ".";
}
}
return valueTemp;
};
使用方式
/**
* @description 数字输入框
*/
import { Input, InputProps } from 'antd'
import styled from 'styled-components'
import _Number from './utils'
import { validateInput } from '@/utils/utils'
import { useEffect, useState } from 'react'
/**
*
* @param unit 单位
* @param value 原数据
* @description 日:整数,年:一位小数,其他:两位小数
*/
export const FormatNumber = (unit: string, value: string) => {
if (unit === '日') {
return value
}
}
const InputWrapper = styled.div`
width: 80px;
margin: 0 8px;
.ant-input-affix-wrapper {
padding: 0 0 0 8px;
border-color: ${(props) =>
props.isError ? '#E64A00' : '#D4D7DD'} !important;
}
.ant-input {
height: 28px;
border-color: ${(props) =>
props.isError ? '#E64A00' : '#D4D7DD'} !important;
.ant-input {
height: 27px;
line-height: 27px;
padding: 0 8px;
}
}
`
interface NewInputNumberProps extends InputProps {
isError?: boolean // 用来校验为空时的样式
min?: number // 最小值
max?: number // 最大值
precision?: number // 数值精度
}
const SInputNumber = (props: NewInputNumberProps) => {
const { onChange, min, precision, max } = props
const [curValue, setCurValue] = useState<number | string | null>()
let newProps = { ...props }
delete newProps.isError
delete newProps.style
const onChangeNumber = (e) => {
// 处理后的值
const res = validateInput(e.target.value, precision, min, max)
if (curValue?.toString() !== res?.toString()) {
onChange(res)
}
setCurValue(curValue)
}
const onBlurNumber = (e) => {
const res = validateInput(e.target.value, precision, min)
if (
res &&
res?.length > 1 &&
res.toString().indexOf('.') === res.toString().length - 1
) {
onChange(_Number.toNumber(res))
}
}
useEffect(() => {
setCurValue(props.value)
}, [props.value])
return (
<InputWrapper isError={props.isError} style={props.style}>
<Input {...newProps} onChange={onChangeNumber} onBlur={onBlurNumber} />
</InputWrapper>
)
}
export default SInputNumber
以下方法引自rc-inputnumber
// '1.' '1x' 'xx' '' => are not complete numbers
isNotCompleteNumber: function isNotCompleteNumber(num) {
return (
isNaN(num) ||
num === '' ||
num.toString().indexOf('.') === num.toString().length - 1
)
},
toNumber: function toNumber(num) {
if (this.isNotCompleteNumber(num)) {
return Number(num);
}
return num;
},