🎈 perf(优化所有输入框):

This commit is contained in:
2022-11-08 13:49:57 +08:00
parent d06f4137c6
commit 812971f6b2
14 changed files with 1285 additions and 1059 deletions
+53 -47
View File
@@ -1,61 +1,67 @@
import { Input, Text, Textarea, View } from '@tarojs/components'
import { memo } from 'react'
import './index.scss'
import { Input, Text, Textarea, View } from "@tarojs/components"
import { memo } from "react"
import "./index.scss"
interface ListParams{
label: string, //左边label
onInput?: (ev:Object)=>void, // 输入框输入
onClick?:()=>any, //点击列表
placeholder?:string, // 提示文本
children?: any, // 插槽
type?: string // 类型:1.input,2.textarea,3.select,
primordialType?: 'text'|'number'|'idcard'|'digit'
value?: any,
style?: object, //整行样式
labelStyle?: object, // label样式
contentStyle?: object,
interface ListParams {
label: string //左边label
onInput?: (ev: Object) => void // 输入框输入
onClick?: () => any //点击列表
placeholder?: string // 提示文本
children?: any // 插槽
type?: string // 类型:1.input,2.textarea,3.select,
primordialType?: 'text' | 'number' | 'idcard' | 'digit'
value?: any
style?: object //整行样式
labelStyle?: object // label样式
contentStyle?: object
required?: boolean
}
// 表单列表
const FromList = memo((props:ListParams)=>{
const {type="input",value="",style={},labelStyle={},contentStyle={},required=false} = props;
const FromList = memo((props: ListParams) => {
const { type = 'input', value = '', style = {}, labelStyle = {}, contentStyle = {}, required = false } = props
return (
<View style={style} className="form-list">
<View style={labelStyle} className={`form-list-label ${required&&"form-list-label-required"}`}>{props.label}</View>
<View onClick={props?.onClick} className="form-list-right">
{
props.children??
<View style={contentStyle} onClick={props?.onClick} className="form-list-right-meet">
{
type=="input"?
<View className="form-list-input">
<Input value={value} placeholder-class="phcolor" type={props.primordialType||'text'} onInput={props?.onInput} placeholder={props.placeholder} />
{value&&
<View><Text onClick={()=>props.onInput&&props.onInput({detail: {value: ""}})} className="iconfont icon-qingkong"/></View>
}
</View>:
type=="textarea"?<Textarea value={value} placeholder-class="phcolor" onInput={props?.onInput} placeholder={props.placeholder} />:
<>
{
props.value?<View>{value}</View>:
<View className="form-list-right-placeholder">
{props.placeholder}
<View style={style} className='form-list'>
<View style={labelStyle} className={`form-list-label ${required && 'form-list-label-required'}`}>
{props.label}
</View>
<View onClick={props?.onClick} className='form-list-right'>
{props.children ?? (
<View style={contentStyle} onClick={props?.onClick} className='form-list-right-meet'>
{type == 'input' ? (
<View className='form-list-input'>
<Input
alwaysEmbed={true}
cursorSpacing={150}
value={value}
placeholder-class='phcolor'
type={props.primordialType || 'text'}
onInput={props?.onInput}
placeholder={props.placeholder}
/>
{value && (
<View>
<Text onClick={() => props.onInput && props.onInput({ detail: { value: '' } })} className='iconfont icon-qingkong' />
</View>
}
<View className="form-list-right-enter"><Text className="iconfont icon-a-moreback"></Text></View>
)}
</View>
) : type == 'textarea' ? (
<Textarea value={value} placeholder-class='phcolor' onInput={props?.onInput} placeholder={props.placeholder} />
) : (
<>
{props.value ? <View>{value}</View> : <View className='form-list-right-placeholder'>{props.placeholder}</View>}
<View className='form-list-right-enter'>
<Text className='iconfont icon-a-moreback'></Text>
</View>
</>
}
)}
</View>
}
)}
</View>
</View>
)
})
const A = ()=>{
}
export default FromList;
const A = () => {}
export default FromList
+51 -50
View File
@@ -1,63 +1,64 @@
import { Input, Text, Textarea, View } from '@tarojs/components'
import { memo } from 'react'
import './index.scss'
import { Input, Text, Textarea, View } from "@tarojs/components"
import { memo } from "react"
import "./index.scss"
interface ListParams{
label: string, //左边label
onInput?: (ev:Object)=>void, // 输入框输入
onClick?:()=>any, //点击列表
placeholder?:string, // 提示文本
children?: any, // 插槽
type?: string // 类型:1.input,2.textarea,3.select
value?: any,
style?: object, //整行样式
labelStyle?: object, // label样式
contentStyle?: object,
required?: boolean,
showIcon?: boolean, // 是否显示右边的箭头,type=select
interface ListParams {
label: string //左边label
onInput?: (ev: Object) => void // 输入框输入
onClick?: () => any //点击列表
placeholder?: string // 提示文本
children?: any // 插槽
type?: string // 类型:1.input,2.textarea,3.select
value?: any
style?: object //整行样式
labelStyle?: object // label样式
contentStyle?: object
required?: boolean
showIcon?: boolean // 是否显示右边的箭头,type=select
}
// 表单列表
const FromList = memo((props:ListParams)=>{
const {type="input",value="",style={},labelStyle={},contentStyle={},required=false,showIcon=true} = props;
const FromList = memo((props: ListParams) => {
const { type = 'input', value = '', style = {}, labelStyle = {}, contentStyle = {}, required = false, showIcon = true } = props
return (
<View style={style} className="From-list-certification">
<View style={labelStyle} className={`From-list-certification-label ${required&&"From-list-certification-label-required"}`}>{props.label}</View>
<View onClick={props?.onClick} className="From-list-certification-right">
{
props.children??
<View style={contentStyle} onClick={props?.onClick} className="From-list-certification-right-meet">
{
type=="input"?
<View className="From-list-certification-input">
<Input value={value} placeholder-class="phcolor" onInput={props?.onInput} placeholder={props.placeholder} />
{value&&
<View><Text onClick={()=>props.onInput&&props.onInput({detail: {value: ""}})} className="iconfont icon-qingkong"/></View>
}
</View>:
type=="textarea"?<Textarea value={value} placeholder-class="phcolor" onInput={props?.onInput} placeholder={props.placeholder} />:
<>
{
props.value?<View>{value}</View>:
<View className="From-list-certification-right-placeholder">
{props.placeholder}
<View style={style} className='From-list-certification'>
<View style={labelStyle} className={`From-list-certification-label ${required && 'From-list-certification-label-required'}`}>
{props.label}
</View>
<View onClick={props?.onClick} className='From-list-certification-right'>
{props.children ?? (
<View style={contentStyle} onClick={props?.onClick} className='From-list-certification-right-meet'>
{type == 'input' ? (
<View className='From-list-certification-input'>
<Input
alwaysEmbed={true}
cursorSpacing={150}
value={value}
placeholder-class='phcolor'
onInput={props?.onInput}
placeholder={props.placeholder}
/>
{value && (
<View>
<Text onClick={() => props.onInput && props.onInput({ detail: { value: '' } })} className='iconfont icon-qingkong' />
</View>
}
<View className="From-list-certification-right-enter">
{showIcon&&<Text className="iconfont icon-a-moreback"></Text>}
</View>
)}
</View>
) : type == 'textarea' ? (
<Textarea value={value} placeholder-class='phcolor' onInput={props?.onInput} placeholder={props.placeholder} />
) : (
<>
{props.value ? <View>{value}</View> : <View className='From-list-certification-right-placeholder'>{props.placeholder}</View>}
<View className='From-list-certification-right-enter'>{showIcon && <Text className='iconfont icon-a-moreback'></Text>}</View>
</>
}
)}
</View>
}
)}
</View>
</View>
)
})
const A = ()=>{
}
export default FromList;
const A = () => {}
export default FromList
+100 -105
View File
@@ -1,115 +1,110 @@
import { Input, View } from "@tarojs/components"
import { useEffect, useMemo, useRef, useState } from "react"
import { Input, View } from '@tarojs/components'
import { useEffect, useMemo, useRef, useState } from 'react'
import Big from 'big.js'
import styles from "./index.module.scss"
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, //是否禁用
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 ({minNum = 0, maxNum = 10000, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false}: params) => {
const [value, setValue] = useState<any>({count:defaultNum})
export default ({ minNum = 0, maxNum = 10000, step = 1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false }: params) => {
const [value, setValue] = useState<any>({ count: defaultNum })
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 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 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 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 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)
}
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'
disabled={disable}
/>
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={() => onPlus()}>+</View>
</View>
)
}
}
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' disabled={disable} alwaysEmbed={true} cursorSpacing={150} />
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={() => onPlus()}>
+
</View>
</View>
)
}
+97 -101
View File
@@ -1,111 +1,107 @@
import { Input, View } from "@tarojs/components"
import { useEffect, useMemo, useRef, useState } from "react"
import { Input, View } from '@tarojs/components'
import { useEffect, useMemo, useRef, useState } from 'react'
import Big from 'big.js'
import styles from "./index.module.scss"
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
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})
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 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 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 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 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)
}
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'
/>
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={() => onPlus()}>+</View>
</View>
)
}
}
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>
)
}
+135 -107
View File
@@ -1,118 +1,146 @@
import { GetProductKindListApi } from "@/api/material";
import Popup, {Params as PopuParams} from "@/components/popup"
import { Input, ScrollView, Text, Textarea, View } from "@tarojs/components"
import { useDidShow } from "@tarojs/taro";
import classnames from "classnames";
import { memo, useEffect, useRef, useState } from "react";
import styles from './index.module.scss'
import { GetProductKindListApi } from '@/api/material'
import Popup, { Params as PopuParams } from '@/components/popup'
import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components'
import { useDidShow } from '@tarojs/taro'
import classnames from 'classnames'
import { memo, useEffect, useRef, useState } from 'react'
import styles from './index.module.scss'
type params = {
onFiltr?: (val:object) => void //确定搜索
onRest?: (val:Object) => void //重置
onFiltr?: (val: object) => void //确定搜索
onRest?: (val: Object) => void //重置
} & PopuParams
export default memo(({onClose, onFiltr, show = false, onRest}:params) => {
export default memo(({ onClose, onFiltr, show = false, onRest }: params) => {
//搜索条件
const [filterObj, setFilterObj] = useState({
seriesName: '',
seriesId: '',
width: '',
weight: '',
element: '',
})
//搜索条件
const [filterObj, setFilterObj] = useState({
seriesName: '',
seriesId: '',
width: '',
weight: '',
element: '',
})
const selectFieldValue = useRef({ width: '幅宽', weight: '克重', element: '成分', seriesName: '系列' })
const selectFieldValue = useRef({width:'幅宽', weight:'克重', element:'成分', seriesName:'系列'})
//获取系列
const { fetchData: kindFetchData } = GetProductKindListApi()
const [kindList, setKindList] = useState<any[]>([])
const getCategoryList = async () => {
let { data } = await kindFetchData()
setKindList(data.list)
}
//获取系列
const {fetchData: kindFetchData} = GetProductKindListApi()
const [kindList, setKindList] = useState<any[]>([])
const getCategoryList = async () => {
let {data} = await kindFetchData()
setKindList(data.list)
useEffect(() => {
show && getCategoryList()
}, [show])
//切换系列
const changeKind = (e) => {
setFilterObj({ ...filterObj, seriesId: e.id, seriesName: e.name })
}
const onCloseEven = () => {
onClose?.()
}
//重置数据
const onRestEven = () => {
let res = {
seriesName: '',
seriesId: '',
width: '',
weight: '',
element: '',
}
setFilterObj(res)
onFiltr?.(filterObj)
onClose?.()
}
useEffect(() => {
show&&getCategoryList()
}, [show])
//提交搜索
const onVerify = () => {
onFiltr?.({ data: filterObj, field: selectFieldValue.current })
onClose?.()
}
//切换系列
const changeKind = (e) => {
setFilterObj({...filterObj, seriesId:e.id, seriesName: e.name})
}
//获取幅宽或克重输入值或成分
const setFieldData = (e, field) => {
filterObj[field] = e.detail.value
setFilterObj({ ...filterObj })
}
const onCloseEven = () => {
onClose?.()
}
//重置数据
const onRestEven = () => {
let res = {
seriesName: '',
seriesId: '',
width: '',
weight: '',
element: '',
}
setFilterObj(res)
onFiltr?.(filterObj)
onClose?.()
}
//提交搜索
const onVerify = () => {
onFiltr?.({data:filterObj, field: selectFieldValue.current})
onClose?.()
}
//获取幅宽或克重输入值或成分
const setFieldData = (e, field) => {
filterObj[field] = e.detail.value
setFilterObj({...filterObj})
}
return (
<Popup position="right" show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}>
<View className={styles.popup_main}>
<View className={styles.popup_title}>全部筛选</View>
<ScrollView scrollY className={styles.scroll}>
<View className={styles.popup_filter}>
<View className={styles.popup_filter_item}>
<View className={styles.title}>系列</View>
<View className={styles.btn_list}>
{kindList.map(item => <View key={item.id} onClick={() => changeKind(item)} className={classnames(styles.btn_item, (filterObj.seriesId == item.id)&&styles.select_btn_item)}>{item.name}</View>)}
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>幅宽</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}><Input value={filterObj.width} onBlur={(e) => setFieldData(e,'width')} placeholder="请输入幅宽" placeholderStyle="font-size: 26rpx"/></View>
<View className={styles.unit}>cm</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>克重</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}><Input value={filterObj.weight} onBlur={(e) => setFieldData(e,'weight')} placeholder="请输入克重" placeholderStyle="font-size: 26rpx"/></View>
<View className={styles.unit}>kg</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>成分</View>
<View className={styles.btn_list_element}>
<Textarea placeholder="请输入" cursorSpacing={60} value={filterObj.element} onInput={(e) => setFieldData(e, 'element')}/>
</View>
</View>
<View className="common_safe_area_y"></View>
</View>
</ScrollView>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onRestEven()}>重置</View>
<View className={styles.verify_btn } onClick={() => onVerify()}>确认</View>
</View>
</View>
return (
<Popup position='right' show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}>
<View className={styles.popup_main}>
<View className={styles.popup_title}>全部筛选</View>
<ScrollView scrollY className={styles.scroll}>
<View className={styles.popup_filter}>
<View className={styles.popup_filter_item}>
<View className={styles.title}>系列</View>
<View className={styles.btn_list}>
{kindList.map((item) => (
<View
key={item.id}
onClick={() => changeKind(item)}
className={classnames(styles.btn_item, filterObj.seriesId == item.id && styles.select_btn_item)}>
{item.name}
</View>
))}
</View>
</View>
</Popup>
)
})
<View className={styles.popup_filter_item}>
<View className={styles.title}>幅宽</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}>
<Input
alwaysEmbed={true}
cursorSpacing={150}
value={filterObj.width}
onBlur={(e) => setFieldData(e, 'width')}
placeholder='请输入幅宽'
placeholderStyle='font-size: 26rpx'
/>
</View>
<View className={styles.unit}>cm</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>克重</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}>
<Input
value={filterObj.weight}
alwaysEmbed={true}
cursorSpacing={150}
onBlur={(e) => setFieldData(e, 'weight')}
placeholder='请输入克重'
placeholderStyle='font-size: 26rpx'
/>
</View>
<View className={styles.unit}>kg</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>成分</View>
<View className={styles.btn_list_element}>
<Textarea placeholder='请输入' cursorSpacing={60} value={filterObj.element} onInput={(e) => setFieldData(e, 'element')} />
</View>
</View>
<View className='common_safe_area_y'></View>
</View>
</ScrollView>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onRestEven()}>
重置
</View>
<View className={styles.verify_btn} onClick={() => onVerify()}>
确认
</View>
</View>
</View>
</View>
</Popup>
)
})
+155 -117
View File
@@ -1,128 +1,166 @@
import { GetProductKindListApi } from "@/api/material";
import Popup, {Params as PopuParams} from "@/components/popup"
import { Input, ScrollView, Text, Textarea, View } from "@tarojs/components"
import { useDidShow } from "@tarojs/taro";
import classnames from "classnames";
import { useEffect, useState } from "react";
import styles from './index.module.scss'
import { GetProductKindListApi } from '@/api/material'
import Popup, { Params as PopuParams } from '@/components/popup'
import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components'
import { useDidShow } from '@tarojs/taro'
import classnames from 'classnames'
import { useEffect, useState } from 'react'
import styles from './index.module.scss'
type params = {
onFiltr?: (val:object) => void
onFiltr?: (val: object) => void
} & PopuParams
export default ({onClose, onFiltr, show = false}:params) => {
export default ({ onClose, onFiltr, show = false }: params) => {
//搜索条件
const [filterObj, setFilterObj] = useState({
seriesId: '',
minWidth: '',
maxWidth: '',
minWeight: '',
maxWeight: '',
element: '',
})
//搜索条件
const [filterObj, setFilterObj] = useState({
seriesId: '',
minWidth: '',
maxWidth: '',
minWeight: '',
maxWeight: '',
element: ''
//获取系列
const { fetchData: kindFetchData } = GetProductKindListApi()
const [kindList, setKindList] = useState<any[]>([])
const getCategoryList = async () => {
let { data } = await kindFetchData()
setKindList(data.list)
}
useEffect(() => {
show && getCategoryList()
}, [show])
//切换系列
const changeKind = (e) => {
setFilterObj({ ...filterObj, seriesId: e.id })
}
const onCloseEven = () => {
onClose?.()
}
const onRest = () => {
console.log('12123')
setFilterObj({
seriesId: '',
minWidth: '',
maxWidth: '',
minWeight: '',
maxWeight: '',
element: '',
})
}
useEffect(() => {
console.log(filterObj)
}, [filterObj])
//获取系列
const {fetchData: kindFetchData} = GetProductKindListApi()
const [kindList, setKindList] = useState<any[]>([])
const getCategoryList = async () => {
let {data} = await kindFetchData()
setKindList(data.list)
}
const onVerify = () => {
console.log(filterObj)
onFiltr?.(filterObj)
}
useEffect(() => {
show&&getCategoryList()
}, [show])
const setNumber = (e, field) => {
console.log(e)
let num = parseFloat(e.detail.value)
if (isNaN(num)) {
filterObj[field] = null
} else {
filterObj[field] = parseFloat(num.toFixed(2))
}
setFilterObj({ ...filterObj })
}
//切换系列
const changeKind = (e) => {
setFilterObj({...filterObj, seriesId:e.id})
}
const onCloseEven = () => {
onClose?.()
}
const onRest = () => {
console.log('12123')
setFilterObj({
seriesId: '',
minWidth: '',
maxWidth: '',
minWeight: '',
maxWeight: '',
element: ''
})
}
useEffect(() => {
console.log(filterObj)
}, [filterObj])
const onVerify = () => {
console.log(filterObj)
onFiltr?.(filterObj)
}
const setNumber = (e, field) => {
console.log(e)
let num = parseFloat(e.detail.value)
if(isNaN(num)) {
filterObj[field] = null
} else {
filterObj[field] = parseFloat(num.toFixed(2))
}
setFilterObj({...filterObj})
}
const setElement = (e) => {
let res = e.detail.value
setFilterObj({...filterObj, element:res})
}
return (
<Popup position="right" show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}>
<View className={styles.popup_main}>
<View className={styles.popup_title}>全部筛选</View>
<ScrollView scrollY className={styles.scroll}>
<View className={styles.popup_filter}>
<View className={styles.popup_filter_item}>
<View className={styles.title}>系列</View>
<View className={styles.btn_list}>
{kindList.map(item => <View key={item.id} onClick={() => changeKind(item)} className={classnames(styles.btn_item, (filterObj.seriesId == item.id)&&styles.select_btn_item)}>{item.name}</View>)}
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>幅宽</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}><Input value={filterObj.minWidth} type="digit" onBlur={(e) => setNumber(e,'minWidth')} placeholder="请输入幅宽" placeholderStyle="font-size: 26rpx"/></View>
<View className={styles.unit}>cm</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>克重</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}><Input type="digit" value={filterObj.minWeight} onBlur={(e) => setNumber(e,'minWeight')} placeholder="自定义最低值" placeholderStyle="font-size: 26rpx"/></View>
<Text>—</Text>
<View className={styles.btn_width}><Input type="digit" value={filterObj.maxWeight} onBlur={(e) => setNumber(e,'maxWeight')} placeholder="自定义最高值" placeholderStyle="font-size: 26rpx"/></View>
<View className={styles.unit}>g</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>成分</View>
<View className={styles.btn_list_element}>
<Textarea placeholder="请输入" cursorSpacing={60} value={filterObj.element} onInput={(e) => setElement(e)}/>
</View>
</View>
<View className="common_safe_area_y"></View>
</View>
</ScrollView>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onRest()}>重置</View>
<View className={styles.verify_btn } onClick={() => onVerify()}>确认</View>
</View>
const setElement = (e) => {
let res = e.detail.value
setFilterObj({ ...filterObj, element: res })
}
return (
<Popup position='right' show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}>
<View className={styles.popup_main}>
<View className={styles.popup_title}>全部筛选</View>
<ScrollView scrollY className={styles.scroll}>
<View className={styles.popup_filter}>
<View className={styles.popup_filter_item}>
<View className={styles.title}>系列</View>
<View className={styles.btn_list}>
{kindList.map((item) => (
<View
key={item.id}
onClick={() => changeKind(item)}
className={classnames(styles.btn_item, filterObj.seriesId == item.id && styles.select_btn_item)}>
{item.name}
</View>
))}
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>幅宽</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}>
<Input
alwaysEmbed={true}
cursorSpacing={150}
value={filterObj.minWidth}
type='digit'
onBlur={(e) => setNumber(e, 'minWidth')}
placeholder='请输入幅宽'
placeholderStyle='font-size: 26rpx'
/>
</View>
<View className={styles.unit}>cm</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>克重</View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}>
<Input
type='digit'
value={filterObj.minWeight}
onBlur={(e) => setNumber(e, 'minWeight')}
placeholder='自定义最低值'
placeholderStyle='font-size: 26rpx'
alwaysEmbed={true}
cursorSpacing={150}
/>
</View>
<Text>—</Text>
<View className={styles.btn_width}>
<Input
type='digit'
value={filterObj.maxWeight}
onBlur={(e) => setNumber(e, 'maxWeight')}
placeholder='自定义最高值'
placeholderStyle='font-size: 26rpx'
alwaysEmbed={true}
cursorSpacing={150}
/>
</View>
<View className={styles.unit}>g</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}>成分</View>
<View className={styles.btn_list_element}>
<Textarea placeholder='请输入' cursorSpacing={60} value={filterObj.element} onInput={(e) => setElement(e)} />
</View>
</View>
</Popup>
)
}
<View className='common_safe_area_y'></View>
</View>
</ScrollView>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onRest()}>
重置
</View>
<View className={styles.verify_btn} onClick={() => onVerify()}>
确认
</View>
</View>
</View>
</View>
</Popup>
)
}
+89 -59
View File
@@ -1,83 +1,113 @@
import { Input, View } from "@tarojs/components";
import styles from "./index.module.scss"
import CloseBtn from "@/components/closeBtn"
import classnames from "classnames";
import { debounce } from "@/common/util";
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react";
import { Input, View } from '@tarojs/components'
import styles from './index.module.scss'
import CloseBtn from '@/components/closeBtn'
import classnames from 'classnames'
import { debounce } from '@/common/util'
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from 'react'
type Params = {
clickOnSearch?: (val: string) => void
disabled?: false|true,
placeholder?: string,
changeOnSearch?:(any) => void,
showIcon?: false|true,
placeIcon?: 'out'|'inner',
style?: Object,
showBtn?: false|true,
btnStyle?: Object,
btnTitle?: string,
debounceTime?: number //防抖时间,不设默认为零
defaultValue?: string
clickOnSearch?: (val: string) => void
disabled?: false | true
placeholder?: string
changeOnSearch?: (any) => void
showIcon?: false | true
placeIcon?: 'out' | 'inner'
style?: Object
showBtn?: false | true
btnStyle?: Object
btnTitle?: string
debounceTime?: number //防抖时间,不设默认为零
defaultValue?: string
}
export default memo(forwardRef(({
clickOnSearch, //点击筛选按钮触发
changeOnSearch, //输入文字触发
disabled = false, //是否禁用
placeholder = '输入搜索内容',
showIcon = true, //是否显示关闭图标
showBtn = false, //是否显示搜索按钮
btnStyle = {},
placeIcon = 'inner', //搜索图标位置:inner在里面,out在外面
btnTitle = '搜索', //搜索文字
debounceTime = 0, //防抖时间,不设默认为零
defaultValue = '' //默认值
}:Params, ref) => {
const [inputCon , setInputCon] = useState('')
const debounceTimeRef = useRef(0)
useEffect(() => {
export default memo(
forwardRef(
(
{
clickOnSearch, //点击筛选按钮触发
changeOnSearch, //输入文字触发
disabled = false, //是否禁用
placeholder = '输入搜索内容',
showIcon = true, //是否显示关闭图标
showBtn = false, //是否显示搜索按钮
btnStyle = {},
placeIcon = 'inner', //搜索图标位置:inner在里面,out在外面
btnTitle = '搜索', //搜索文字
debounceTime = 0, //防抖时间,不设默认为零
defaultValue = '', //默认值
}: Params,
ref,
) => {
const [inputCon, setInputCon] = useState('')
const debounceTimeRef = useRef(0)
useEffect(() => {
setInputCon(defaultValue)
}, [defaultValue])
}, [defaultValue])
useEffect(() => {
useEffect(() => {
debounceTimeRef.current = debounceTime
}, [debounceTime])
}, [debounceTime])
const onInputEven = (e) => {
const onInputEven = (e) => {
const value = e.detail.value
changeData(value)
}
}
useImperativeHandle(ref, () => ({
clearInput
}))
useImperativeHandle(ref, () => ({
clearInput,
}))
const clearInput = () => {
const clearInput = () => {
setInputCon('')
changeOnSearch?.('')
}
}
const changeData = debounce((value) => {
const changeData = debounce((value) => {
setInputCon(value)
changeOnSearch?.(value)
}, debounceTimeRef.current)
}, debounceTimeRef.current)
const onSearch = () => {
const onSearch = () => {
clickOnSearch?.(inputCon)
}
}
return (
return (
<>
<View className={styles.search_main} >
<View className={styles.search_con}>
{showIcon&&<View className={classnames('iconfont', 'icon-sousuo', styles.icon_a_sousuo1_self, placeIcon=='inner'?styles.icon_inner:styles.icon_out)}></View>}
<Input placeholderStyle='color:#ABABAB; font-size:26rpx' onConfirm={onSearch} className={classnames(placeIcon=='out'&&styles.input_out)} disabled={disabled} value={inputCon} placeholder={placeholder} onInput={(e) => onInputEven(e)}></Input>
{!!inputCon&&<View className={styles.search_closeBtn}>
<CloseBtn onClose={() => clearInput()} styleObj={{width: '20rpx', height:'20rpx', backgroundColor:'#fff', border:'0'}}/>
</View>}
<View className={styles.search_main}>
<View className={styles.search_con}>
{showIcon && (
<View
className={classnames(
'iconfont',
'icon-sousuo',
styles.icon_a_sousuo1_self,
placeIcon == 'inner' ? styles.icon_inner : styles.icon_out,
)}></View>
)}
<Input
alwaysEmbed={true}
cursorSpacing={150}
placeholderStyle='color:#ABABAB; font-size:26rpx'
onConfirm={onSearch}
className={classnames(placeIcon == 'out' && styles.input_out)}
disabled={disabled}
value={inputCon}
placeholder={placeholder}
onInput={(e) => onInputEven(e)}></Input>
{!!inputCon && (
<View className={styles.search_closeBtn}>
<CloseBtn onClose={() => clearInput()} styleObj={{ width: '20rpx', height: '20rpx', backgroundColor: '#fff', border: '0' }} />
</View>
{showBtn&&<View style={btnStyle} className={styles.btn} onClick = {onSearch}>{btnTitle}</View>}
)}
</View>
{showBtn && (
<View style={btnStyle} className={styles.btn} onClick={onSearch}>
{btnTitle}
</View>
)}
</View>
</>
)
}))
)
},
),
)
+55 -45
View File
@@ -1,52 +1,62 @@
import { Input, View } from "@tarojs/components";
import { memo, ReactHTMLElement, ReactNode, useDebugValue, useMemo } from "react";
import styles from './index.module.scss';
import { Input, View } from '@tarojs/components'
import { memo, ReactHTMLElement, ReactNode, useDebugValue, useMemo } from 'react'
import styles from './index.module.scss'
type Params = {
showIcon?: false|true,
disabled?: false|true,
placeholder?: string,
title?: string,
showTitle?: false|true,
showBorder?: false|true,
changeOnInput?: (string) => void,
clickOnInput?: () => void,
children?: ReactNode
height?: string,
titleStyle?: Object,
styleObj?: Object
showIcon?: false | true
disabled?: false | true
placeholder?: string
title?: string
showTitle?: false | true
showBorder?: false | true
changeOnInput?: (string) => void
clickOnInput?: () => void
children?: ReactNode
height?: string
titleStyle?: Object
styleObj?: Object
}
export default memo((props: Params) => {
let {
showTitle = true,
title = '标题',
showIcon = false,
disabled = false,
placeholder = '请输入',
showBorder = true,
changeOnInput,
clickOnInput,
height = '80rpx',
titleStyle = {}
} = props
let {
showTitle = true,
title = '标题',
showIcon = false,
disabled = false,
placeholder = '请输入',
showBorder = true,
changeOnInput,
clickOnInput,
height = '80rpx',
titleStyle = {},
} = props
let stylen = useMemo(() => {
if(!showBorder) {
return { borderBottom: 0 }
}
return {}
}, [showBorder])
return (
<View className={styles.searchInput_main} style={{height: height, ...stylen}}>
{showTitle&&<View className={styles.searchInput_title} style={titleStyle}>{title}</View>}
<View className={styles.searchInput_con}>
{!props.children&&<Input disabled={disabled} placeholder={placeholder} onClick={() => clickOnInput?.()} onInput={(e) => changeOnInput?.(e.detail.value)}/>
||<>{props.children}</>
}
</View>
{showIcon&&<View className={`iconfont icon-jiantou ${styles.icon_more_self}`}></View>}
let stylen = useMemo(() => {
if (!showBorder) {
return { borderBottom: 0 }
}
return {}
}, [showBorder])
return (
<View className={styles.searchInput_main} style={{ height: height, ...stylen }}>
{showTitle && (
<View className={styles.searchInput_title} style={titleStyle}>
{title}
</View>
)
})
)}
<View className={styles.searchInput_con}>
{(!props.children && (
<Input
alwaysEmbed={true}
cursorSpacing={150}
disabled={disabled}
placeholder={placeholder}
onClick={() => clickOnInput?.()}
onInput={(e) => changeOnInput?.(e.detail.value)}
/>
)) || <>{props.children}</>}
</View>
{showIcon && <View className={`iconfont icon-jiantou ${styles.icon_more_self}`}></View>}
</View>
)
})