封装单个picker:
import React, { useState } from 'react' import { View, PickerView, PickerViewColumn } from '@tarojs/components' import classnames from 'classnames' import './index.scss' export interface IPicker { name: string show: boolean list: any[] } export const INIT_PICKER: IPicker = { name: '', show: false, list: [] } interface IProps extends IPicker { onConfirm: (any) => void } const CustomPicker = (props: IProps) => { const { list, show, onConfirm } = props const [current, setCurrent] = useState<any>(null) const handleChange = (e: any) => { const index = e.detail.value[0] setCurrent(list[index]) } const handleConfirm = (isConfirm: boolean) => { if (isConfirm) { onConfirm(current || list[0]) } else { onConfirm(null) } } return ( <View className={classnames('picker', show && 'show')}> <View className="mask show" onClick={() => onConfirm(null)}></View> <View className="picker-content"> <View className="dialog-header"> <View className="dialog-button cancel" onClick={() => handleConfirm(false)}>取消</View> <View className="dialog-button" onClick={() => handleConfirm(true)}>确定</View> </View> <PickerView className='picker-view-wrap' onChange={handleChange}> <PickerViewColumn> { list.map((item: any, index: number) => { return <View className="picker-item" key={index}>{item.name}</View> }) } </PickerViewColumn> </PickerView> </View> </View> ) } export default CustomPicker
scss:
.picker { position: absolute; top: 0; bottom: 0; width: 100%; height: 100vh; visibility: hidden; &.show { visibility: visible; .picker-content { transform: translateY(0); transition: all 0.4s ease; } } .picker-content { position: fixed; bottom: 0; width: 100%; background-color: $white; transform: translateY(150%); transition: all 0.4s ease; z-index: 99; .dialog-header { width: 100%; background: $bg-color; display: flex; justify-content: space-between; align-items: center; .dialog-button { display: inline-block; text-align: center; font-size: 32px; color: $primary-color; padding: 30px; &.cancel { color: $text-color; } } } .picker-view-wrap { width: 100%; height: 400px; .picker-item { line-height: 70px; font-size: 36px; text-align: center; } } } }
使用:
const INIT_PICKER_VALUE = { areaList: {} } const [picker, setPicker] = useState<IPicker>(INIT_PICKER) const [pickerValue, setPickerValue] = useState<any>(INIT_PICKER_VALUE) const selectPicker = (name: string) => { setPicker({ name, show: true, list: houseAttr[name] }) } const handlePickerConfirm = (item: any) => { if (item) { setPickerValue({ ...pickerValue, [picker.name]: item }) } setPicker({ name: '', show: false, list: [] }) } const renderPickerValue = (value: string) => { return value ? <Text className="input-text">{value}</Text> : <Text className="input-placeholder">请选择</Text> } const renderPicker = (name: string, text: string) => ( <View className="sale-item mt20" onClick={() => selectPicker(name)}> <View className="item-text">{text}</View> <View className="item-input"> {renderPickerValue(pickerValue[name].name)} </View> <View className="item-icon"> <Text className="iconfont iconarrow-right-bold"></Text> </View> </View> ) const customPicker = () => useMemo(() => { return ( <CustomPicker name={picker.name} show={picker.show} list={picker.list} onConfirm={handlePickerConfirm} ></CustomPicker> ) }, [picker]) {renderPicker('areaList', '区域')} {customPicker()}