132 lines
3.6 KiB
TypeScript

import { View } from '@tarojs/components'
import Big from 'big.js'
import InputX from '../InputX'
import styles from './index.module.scss'
import { usePropsValue } from '@/use/useCommon'
interface params {
minNum?: number // 最小值
maxNum?: number // 最大值
step?: number // 步长
defaultNum?: number // 默认值
digits?: number // 多少位小数
onChange?: (val: number) => void
onBlue?: (val: number) => void // 失去焦点触发
onClickBtn?: (val: number) => void
unit?: string
disable?: boolean // 是否禁用
}
const Counter = ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange: onValueChange, onBlue, onClickBtn, unit = '', disable = false }: params) => {
const [value, setValue] = usePropsValue<number>({
value: defaultNum,
defaultValue: defaultNum,
onChange: (nextValue) => {
onValueChange && onValueChange(nextValue)
},
})
// 保留小数
const formatDigits = (num) => {
num = `${num}`
if (num.includes('.') && digits > 0) {
console.log('num::', num.includes('.'))
const res = num.split('.')
const last_num = res[1].substr(0, digits)
return `${res[0]}.${last_num}`
}
return parseFloat(num)
}
// 加号
const onPlus = (event) => {
event.stopPropagation()
if (disable) { return false }
let num_res = Big(value).add(step).toNumber()
num_res = num_res >= maxNum ? maxNum : num_res
num_res = formatDigits(num_res)
setValue(num_res)
onClickBtn?.(parseFloat(num_res))
}
// 减号
const minus = (event) => {
event.stopPropagation()
if (disable) { return false }
let num_res = Big(value).minus(step).toNumber()
num_res = num_res < minNum ? minNum : num_res
setValue(num_res)
onClickBtn?.(parseFloat(num_res))
}
// 检查数据
const checkData = (val) => {
const num = parseFloat(val)
if (num > maxNum) { return maxNum }
if (num < minNum) { return minNum }
return val
}
const onInputEven = (e) => {
const res = e.detail.value
if (res === '') {
setValue(minNum)
return minNum
}
else if (!Number.isNaN(Number(res))) {
let count = formatDigits(res)
count = checkData(count)
setValue(count as number)
return count
}
else {
const num = parseFloat(res)
if (!Number.isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue(count as number)
return count
}
else {
setValue(defaultNum)
return defaultNum
}
}
}
const onBluerEven = () => {
const num = parseFloat(String(value))
console.log('onInputEven res===>', num)
if (!Number.isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue(count as number)
onBlue?.(count as number)
return count
}
else {
setValue(defaultNum)
onBlue?.(defaultNum)
return defaultNum
}
}
const noop = (e) => {
e.stopPropagation()
}
return (
<View className={styles.main}>
<View className={styles.reduce} onClick={minus}>
-
</View>
<View className={styles.input} onClick={noop}>
<InputX value={String(value)} onInput={onInputEven} onBlur={onBluerEven} type="digit" disabled={disable} />
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={onPlus}>
+
</View>
</View>
)
}
export default Counter