🎈 perf(优化购物车):
This commit is contained in:
parent
c3a6e017f0
commit
566f429051
136
src/components/counter/index copy.tsx
Normal file
136
src/components/counter/index copy.tsx
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import { Input, View } from '@tarojs/components'
|
||||||
|
import { memo, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
import Big from 'big.js'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
type 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?: true | false //是否禁用
|
||||||
|
}
|
||||||
|
export default memo((props: params) => {
|
||||||
|
return <Counter {...props}></Counter>
|
||||||
|
})
|
||||||
|
|
||||||
|
function areEqual(prevProps: params, nextProps: params) {
|
||||||
|
return (
|
||||||
|
prevProps.defaultNum == nextProps.defaultNum &&
|
||||||
|
prevProps.unit == nextProps.unit &&
|
||||||
|
prevProps.minNum == nextProps.minNum &&
|
||||||
|
prevProps.maxNum == nextProps.maxNum &&
|
||||||
|
prevProps.step == nextProps.step &&
|
||||||
|
prevProps.digits == nextProps.digits
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const Counter = memo((props: params) => {
|
||||||
|
let { minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false } = props
|
||||||
|
const [value, setValue] = useState<any>({ count: defaultNum })
|
||||||
|
// useEffect(() => {
|
||||||
|
// setValue({ count: defaultNum })
|
||||||
|
// }, [defaultNum])
|
||||||
|
console.log('1231231231231212')
|
||||||
|
const onPlus = () => {
|
||||||
|
if (disable) return false
|
||||||
|
let { count } = value
|
||||||
|
let num_res = Big(count).add(step).toNumber()
|
||||||
|
num_res = num_res >= maxNum ? maxNum : num_res
|
||||||
|
num_res = formatDigits(num_res)
|
||||||
|
// setValue({ ...value, count: num_res })
|
||||||
|
onChange?.(parseFloat(num_res))
|
||||||
|
onClickBtn?.(parseFloat(num_res))
|
||||||
|
}
|
||||||
|
const minus = () => {
|
||||||
|
if (disable) return false
|
||||||
|
let { count } = value
|
||||||
|
let num_res = Big(count).minus(step).toNumber()
|
||||||
|
num_res = num_res < minNum ? minNum : num_res
|
||||||
|
// setValue({ ...value, count: num_res })
|
||||||
|
onChange?.(parseFloat(num_res))
|
||||||
|
onClickBtn?.(parseFloat(num_res))
|
||||||
|
}
|
||||||
|
|
||||||
|
//保留小数
|
||||||
|
const formatDigits = (num) => {
|
||||||
|
num = num + ''
|
||||||
|
if (num.includes('.') && digits > 0) {
|
||||||
|
console.log('num::', num.includes('.'))
|
||||||
|
let res = num.split('.')
|
||||||
|
let last_num = res[1].substr(0, digits)
|
||||||
|
return res[0] + '.' + last_num
|
||||||
|
}
|
||||||
|
return parseFloat(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查数据
|
||||||
|
const checkData = (val) => {
|
||||||
|
let num = parseFloat(val)
|
||||||
|
if (num > maxNum) return maxNum
|
||||||
|
if (num < minNum) return minNum
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
const onInputEven = (e) => {
|
||||||
|
// let res = e.detail.value
|
||||||
|
// if (res === '') {
|
||||||
|
// // setValue({ ...value, count: minNum })
|
||||||
|
// onChange?.(minNum)
|
||||||
|
// } else if (!isNaN(Number(res))) {
|
||||||
|
// let count = formatDigits(res)
|
||||||
|
// count = checkData(count)
|
||||||
|
// // setValue({ ...value, count })
|
||||||
|
// onChange?.(parseFloat(count as string))
|
||||||
|
// } else {
|
||||||
|
// let num = parseFloat(res)
|
||||||
|
// if (!isNaN(num)) {
|
||||||
|
// let count = formatDigits(num)
|
||||||
|
// count = checkData(count)
|
||||||
|
// // setValue({ ...value, count })
|
||||||
|
// onChange?.(count as number)
|
||||||
|
// } else {
|
||||||
|
// // setValue({ ...value, count: defaultNum })
|
||||||
|
// onChange?.(defaultNum)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
const onBluerEven = (e) => {
|
||||||
|
let num = parseFloat(e.detail.value)
|
||||||
|
if (!isNaN(num)) {
|
||||||
|
let count = formatDigits(num)
|
||||||
|
count = checkData(count)
|
||||||
|
// setValue({ ...value, count })
|
||||||
|
onBlue?.(count as number)
|
||||||
|
} else {
|
||||||
|
// setValue({ ...value, count: defaultNum })
|
||||||
|
onBlue?.(minNum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View className={styles.main}>
|
||||||
|
<View className={styles.reduce} onClick={() => minus()}>
|
||||||
|
-
|
||||||
|
</View>
|
||||||
|
<View className={styles.input}>
|
||||||
|
<Input
|
||||||
|
value={String(props.defaultNum)}
|
||||||
|
onInput={onInputEven}
|
||||||
|
onBlur={onBluerEven}
|
||||||
|
type='digit'
|
||||||
|
disabled={disable}
|
||||||
|
alwaysEmbed={true}
|
||||||
|
cursorSpacing={150}
|
||||||
|
/>
|
||||||
|
<View className={styles.unit}>{unit}</View>
|
||||||
|
</View>
|
||||||
|
<View className={styles.plus} onClick={() => onPlus()}>
|
||||||
|
+
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}, areEqual)
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
.main {
|
.main {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -21,7 +20,7 @@
|
|||||||
height: 46px;
|
height: 46px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 43px;
|
line-height: 43px;
|
||||||
color:#007AFF;
|
color: #007aff;
|
||||||
}
|
}
|
||||||
.input {
|
.input {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -33,7 +32,7 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
input {
|
input {
|
||||||
font-size: $font_size_medium;
|
font-size: $font_size_medium;
|
||||||
text-align: right;
|
// text-align: right;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,5 +41,4 @@
|
|||||||
font-size: $font_size_min;
|
font-size: $font_size_min;
|
||||||
color: $color_font_two;
|
color: $color_font_two;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { Input, View } from '@tarojs/components'
|
import { Input, View } from '@tarojs/components'
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
import { memo, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
type params = {
|
type params = {
|
||||||
@ -12,14 +12,21 @@ type params = {
|
|||||||
onBlue?: (val: number) => void //失去焦点触发
|
onBlue?: (val: number) => void //失去焦点触发
|
||||||
onClickBtn?: (val: number) => void
|
onClickBtn?: (val: number) => void
|
||||||
unit?: string
|
unit?: string
|
||||||
disable?: true | false //是否禁用
|
disabled?: true | false //是否禁用
|
||||||
}
|
}
|
||||||
export default ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false }: params) => {
|
export default memo((props: params) => {
|
||||||
const [value, setValue] = useState<any>({ count: defaultNum })
|
return <Counter {...props}></Counter>
|
||||||
|
})
|
||||||
|
|
||||||
|
const Counter = memo((props: params) => {
|
||||||
|
let { minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disabled = false } = props
|
||||||
|
const [value, setValue] = useState<any>({ count: defaultNum })
|
||||||
|
useEffect(() => {
|
||||||
|
setValue({ count: defaultNum })
|
||||||
|
}, [defaultNum])
|
||||||
const onPlus = () => {
|
const onPlus = () => {
|
||||||
if (disable) return false
|
if (disabled) return false
|
||||||
let { count } = value
|
let count = value.count
|
||||||
let num_res = Big(count).add(step).toNumber()
|
let num_res = Big(count).add(step).toNumber()
|
||||||
num_res = num_res >= maxNum ? maxNum : num_res
|
num_res = num_res >= maxNum ? maxNum : num_res
|
||||||
num_res = formatDigits(num_res)
|
num_res = formatDigits(num_res)
|
||||||
@ -28,8 +35,8 @@ export default ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum =
|
|||||||
onClickBtn?.(parseFloat(num_res))
|
onClickBtn?.(parseFloat(num_res))
|
||||||
}
|
}
|
||||||
const minus = () => {
|
const minus = () => {
|
||||||
if (disable) return false
|
if (disabled) return false
|
||||||
let { count } = value
|
let count = value.count
|
||||||
let num_res = Big(count).minus(step).toNumber()
|
let num_res = Big(count).minus(step).toNumber()
|
||||||
num_res = num_res < minNum ? minNum : num_res
|
num_res = num_res < minNum ? minNum : num_res
|
||||||
setValue({ ...value, count: num_res })
|
setValue({ ...value, count: num_res })
|
||||||
@ -60,37 +67,40 @@ export default ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum =
|
|||||||
const onInputEven = (e) => {
|
const onInputEven = (e) => {
|
||||||
let res = e.detail.value
|
let res = e.detail.value
|
||||||
if (res === '') {
|
if (res === '') {
|
||||||
setValue({ ...value, count: minNum })
|
// setValue({ ...value, count: minNum })
|
||||||
onChange?.(minNum)
|
onChange?.(minNum)
|
||||||
} else if (!isNaN(Number(res))) {
|
} else if (!isNaN(Number(res))) {
|
||||||
let count = formatDigits(res)
|
let count = formatDigits(res)
|
||||||
count = checkData(count)
|
count = checkData(count)
|
||||||
setValue({ ...value, count })
|
// setValue({ ...value, count })
|
||||||
onChange?.(parseFloat(count as string))
|
onChange?.(parseFloat(count as string))
|
||||||
} else {
|
} else {
|
||||||
let num = parseFloat(res)
|
let num = parseFloat(res)
|
||||||
if (!isNaN(num)) {
|
if (!isNaN(num)) {
|
||||||
let count = formatDigits(num)
|
let count = formatDigits(num)
|
||||||
count = checkData(count)
|
count = checkData(count)
|
||||||
setValue({ ...value, count })
|
// setValue({ ...value, count })
|
||||||
onChange?.(count as number)
|
onChange?.(count as number)
|
||||||
} else {
|
} else {
|
||||||
setValue({ ...value, count: defaultNum })
|
// setValue({ ...value, count: defaultNum })
|
||||||
onChange?.(defaultNum)
|
onChange?.(defaultNum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBluerEven = () => {
|
const onBluerEven = (e) => {
|
||||||
let num = parseFloat(value.count)
|
let num = parseFloat(e.detail.value)
|
||||||
if (!isNaN(num)) {
|
if (e.detail.value == '') {
|
||||||
|
onBlue?.(minNum)
|
||||||
|
setValue({ count: minNum })
|
||||||
|
} else if (!isNaN(num)) {
|
||||||
let count = formatDigits(num)
|
let count = formatDigits(num)
|
||||||
count = checkData(count)
|
count = checkData(count)
|
||||||
setValue({ ...value, count })
|
setValue({ count })
|
||||||
onBlue?.(count as number)
|
onBlue?.(count as number)
|
||||||
} else {
|
} else {
|
||||||
setValue({ ...value, count: defaultNum })
|
setValue({ count: minNum })
|
||||||
onBlue?.(defaultNum)
|
onBlue?.(minNum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
@ -99,7 +109,7 @@ export default ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum =
|
|||||||
-
|
-
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.input}>
|
<View className={styles.input}>
|
||||||
<Input value={String(value.count)} onInput={onInputEven} onBlur={onBluerEven} type='digit' disabled={disable} alwaysEmbed={true} cursorSpacing={150} />
|
<Input value={String(value.count)} onInput={onInputEven} onBlur={onBluerEven} disabled={disabled} alwaysEmbed={true} cursorSpacing={150} />
|
||||||
<View className={styles.unit}>{unit}</View>
|
<View className={styles.unit}>{unit}</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.plus} onClick={() => onPlus()}>
|
<View className={styles.plus} onClick={() => onPlus()}>
|
||||||
@ -107,4 +117,4 @@ export default ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum =
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
|
|
||||||
.main{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
width: 100%;
|
|
||||||
.reduce, .plus{
|
|
||||||
font-size: $font_size_big;
|
|
||||||
color: $color_main;
|
|
||||||
width: 46px;
|
|
||||||
height: 46px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content:center;
|
|
||||||
font-size: 50px;
|
|
||||||
background-color: $color_main;
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
.input{
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 5px 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 106px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
input{
|
|
||||||
font-size: $font_size_medium;
|
|
||||||
}
|
|
||||||
.unit{
|
|
||||||
font-size: $font_size_min;
|
|
||||||
color: $color_font_two;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,107 +0,0 @@
|
|||||||
import { Input, View } from '@tarojs/components'
|
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
|
||||||
import Big from 'big.js'
|
|
||||||
import styles from './index.module.scss'
|
|
||||||
type 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
|
|
||||||
}
|
|
||||||
export default ({ minNum = 0, maxNum = 100, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '' }: params) => {
|
|
||||||
const [value, setValue] = useState<any>({ count: defaultNum })
|
|
||||||
|
|
||||||
const onPlus = () => {
|
|
||||||
let { count } = value
|
|
||||||
let num_res = Big(count).add(step).toNumber()
|
|
||||||
num_res = num_res >= maxNum ? maxNum : num_res
|
|
||||||
num_res = formatDigits(num_res)
|
|
||||||
setValue({ ...value, count: num_res })
|
|
||||||
onChange?.(parseFloat(num_res))
|
|
||||||
onClickBtn?.(parseFloat(num_res))
|
|
||||||
}
|
|
||||||
const minus = () => {
|
|
||||||
let { count } = value
|
|
||||||
let num_res = Big(count).minus(step).toNumber()
|
|
||||||
num_res = num_res < minNum ? 0 : num_res
|
|
||||||
setValue({ ...value, count: num_res })
|
|
||||||
onChange?.(parseFloat(num_res))
|
|
||||||
onClickBtn?.(parseFloat(num_res))
|
|
||||||
}
|
|
||||||
|
|
||||||
//保留小数
|
|
||||||
const formatDigits = (num) => {
|
|
||||||
num = num + ''
|
|
||||||
if (num.includes('.') && digits > 0) {
|
|
||||||
console.log('num::', num.includes('.'))
|
|
||||||
let res = num.split('.')
|
|
||||||
let last_num = res[1].substr(0, digits)
|
|
||||||
return res[0] + '.' + last_num
|
|
||||||
}
|
|
||||||
return parseFloat(num)
|
|
||||||
}
|
|
||||||
|
|
||||||
//检查数据
|
|
||||||
const checkData = (val) => {
|
|
||||||
let num = parseFloat(val)
|
|
||||||
if (num > maxNum) return maxNum
|
|
||||||
if (num < minNum) return minNum
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
const onInputEven = (e) => {
|
|
||||||
let res = e.detail.value
|
|
||||||
if (res === '') {
|
|
||||||
setValue({ ...value, count: minNum })
|
|
||||||
onChange?.(minNum)
|
|
||||||
} else if (!isNaN(Number(res))) {
|
|
||||||
let count = formatDigits(res)
|
|
||||||
count = checkData(count)
|
|
||||||
setValue({ ...value, count })
|
|
||||||
onChange?.(parseFloat(count as string))
|
|
||||||
} else {
|
|
||||||
let num = parseFloat(res)
|
|
||||||
if (!isNaN(num)) {
|
|
||||||
let count = formatDigits(num)
|
|
||||||
count = checkData(count)
|
|
||||||
setValue({ ...value, count })
|
|
||||||
onChange?.(count as number)
|
|
||||||
} else {
|
|
||||||
setValue({ ...value, count: defaultNum })
|
|
||||||
onChange?.(defaultNum)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onBluerEven = () => {
|
|
||||||
let num = parseFloat(value.count)
|
|
||||||
if (!isNaN(num)) {
|
|
||||||
let count = formatDigits(num)
|
|
||||||
count = checkData(count)
|
|
||||||
setValue({ ...value, count })
|
|
||||||
onBlue?.(count as number)
|
|
||||||
} else {
|
|
||||||
setValue({ ...value, count: defaultNum })
|
|
||||||
onBlue?.(defaultNum)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<View className={styles.main}>
|
|
||||||
<View className={styles.reduce} onClick={() => minus()}>
|
|
||||||
-
|
|
||||||
</View>
|
|
||||||
<View className={styles.input}>
|
|
||||||
<Input value={String(value.count)} onInput={onInputEven} onBlur={onBluerEven} type='digit' alwaysEmbed={true} cursorSpacing={150} />
|
|
||||||
<View className={styles.unit}>{unit}</View>
|
|
||||||
</View>
|
|
||||||
<View className={styles.plus} onClick={() => onPlus()}>
|
|
||||||
+
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user