taro3.x: Picker优化使用

定义单个Picker选项组件:

import React, { useEffect, useState } from 'react'
import { View, PickerView, PickerViewColumn } from '@tarojs/components'
import classnames from 'classnames'
import findIndex from 'lodash/findIndex'

import './index.scss'

export interface IPicker {
    item: any, //选项对象
    name: string //实例picker标识
    show: boolean //显示picker
    list: any[] //picker列表
}

export const INIT_PICKER: IPicker = {
    item: {},
    name: '',
    show: false,
    list: []
}

interface IProps extends IPicker {
    onConfirm: (any) => void
}

const CustomPicker = (props: IProps) => {
    const { item, list, show, onConfirm } = props
    const [current, setCurrent] = useState<any>({})

    useEffect(() => {
        //同一个生成过程需要setTimeout
        setTimeout(() => {
            if (item.index) { // 是否设置过index
                setCurrent(item)
            } else { //没有设置过index,在列表中找到当前的项的index
                const index = findIndex(list, { name: item.name })
                setCurrent({ ...item, index })
            }
        }, 0);
    }, [item])

    const handleChange = (e: any) => {
        const index = e.detail.value[0]
        setCurrent({ ...list[index], index })
    }

    const handleConfirm = (isConfirm: boolean) => {
        if (isConfirm) {
            onConfirm(current.index ? current : list[0])
        } else {
            onConfirm(null)
       设置回之前的index } } 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} value={[current.index]}><!--设置当前选择项--> <PickerViewColumn> { list.map((item: any, index: number) => { return <View className="picker-item" key={index}>{item.name}</View> }) } </PickerViewColumn> </PickerView> </View> </View> ) } export default CustomPicker

样式:

.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 customPicker = () => useMemo(() => {
        return (
            <CustomPicker
                key={picker.name}
                item={picker.item}
                name={picker.name}
                show={picker.show}
                list={picker.list}
                onConfirm={handlePickerConfirm}
            ></CustomPicker>
        )
    }, [picker])//根据picker项变动更新picker组件触发useEffect更新当前item项

相关方法:

    const handlePickerConfirm = (item: any) => {
        if (item) {
            setPickerValue({
                ...pickerValue,
                [picker.name]: item
            })
        }
        setPicker({
            ...picker,
            show: false,
        })
    }

    const selectPicker = (name: string) => {
        setPicker({
            name,
            show: true,
            list: pickerObject[name],
            item: pickerValue[name].value ? pickerValue[name] : INIT_PICKER_VALUE[name]
        })
    }

picker项:

const renderValue = (value: string) => {
        return value ?
            <Text className="input-text">{value}</Text> :
            <Text className="input-placeholder">请选择</Text>
    }

    const renderPicker = (name: string, text: string) => (
        <View className="calc-item" onClick={() => selectPicker(name)}>
            <View className="item-label">{text}</View>
            <View className="item-input">
                {renderValue(pickerValue[name].name)}
            </View>
            <View className="item-icon">
                <Text className="iconfont iconarrow-right-bold"></Text>
            </View>
        </View>
    )

初始化pickerValue:

const INIT_PICKER_VALUE = {
    loadRatio: {},
    fundPeriod: {
        name: '基金',
        value: '200'
    }
}
    const [picker, setPicker] = useState<IPicker>(INIT_PICKER)
    const [pickerValue, setPickerValue] = useState<any>(INIT_PICKER_VALUE)
 
原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/14009735.html