首页 前端知识 基于taro picker 封装的多级联动选择器

基于taro picker 封装的多级联动选择器

2024-07-24 23:07:18 前端知识 前端哥 385 235 我要收藏

效果如下:

因项目需求,需要做一个省市区街的四级联动,项目用的组件为taro的picker,奈何移动端与pc端共用一个接口,返回的数据并不是picker想要的数据结构(省级只有湖北省,有些区域下面无街道),因此基于picker再次封装

 代码如下:

import { Picker, View } from '@tarojs/components'
import { useRefState } from 'hook-stash'
import React, { useEffect } from 'react'
import { useHttp } from 'hook-stash'
import styles from './index.module.scss'

interface stateDo {
    value: number[],
    ranges: string[][],
    newList: any
}

export default function index(props) {
    const { url, onChange } = props
    const [list] = useHttp(url, { auto: true })
    const [state, setState] = useRefState<stateDo>({
        value: [0, 0, 0, 0],
        ranges: [[], [], []],
        newList: {}
    })
    const handlePickerShow = (e) => {
        setState({
            value: e.detail.value
        })
    }
    const columnChange = (e) => {
        let newVal = state.value
        newVal[e.detail.column] = e.detail.value
        let ranges = [
            [state.newList?.districtName],
            traversal(state.newList),
            traversal(state.newList.children[newVal[1]]),
            // 判断区角标为0
            state.newList.children[newVal[1]].districtCode !== '0' ? traversal(state.newList.children[newVal[1]].children[newVal[2]]) : ['不详']
        ]
        // 过滤code
        let codes = [
            state.newList?.districtCode,
            traversalCode(state.newList)[newVal[1]],
            traversalCode(state.newList.children[newVal[1]])[newVal[2]],
            state.newList.children[newVal[1]].districtCode !== '0' ? traversalCode(state.newList.children[newVal[1]].children[newVal[2]])[newVal[3]] : "0"
        ].filter(el => el !== '0')
        setState({ ranges: ranges, value: newVal })
        onChange(codes[codes.length - 1])
    }
    // 转换districtName
    const traversal = (arr: any[] | any) => {
        if (!!arr?.children) {
            return arr?.children.map(el => el.districtName)
        } else {
            if (arr?.districtCode === "0") {
                return ['不详']
            } else {
                return [arr?.districtName]
            }
        }
    }
    // 转换districtCode
    const traversalCode = (arr: any[] | any) => {
        if (!!arr?.children) {
            return arr?.children.map(el => el.districtCode)
        } else {
            return [arr?.districtCode]
        }
    }
    // 初始化多列数据
    const cityChange = () => {
        const newList = dataChange(list)
        let ranges = [[newList?.districtName],
        traversal(newList),
        ]
        if (!!newList) {
            setState({
                ranges: ranges,
                newList: newList
            })
            let codes = [newList?.districtCode]
            onChange(codes[codes.length - 1])
        }
        return ranges
    }

    // 递归初始化树形数据
    const dataChange = (list) => {
        if (list?.children) {
            const option = { districtCode: "0", districtName: "不详" }
            list.children.unshift(option)
            list.children.map(el => {
                dataChange(el)
            })
        }
        return list
    }

    useEffect(() => {
        cityChange()
    }, [list])
    return (
        <View className={styles.manageBox}>
            <Picker mode='multiSelector' value={state.value} range={state.ranges} onChange={handlePickerShow} onColumnChange={columnChange} >
                <View>
                    {state.ranges &&
                        <View>
                            {state.ranges[state.value[0]]}
                            {state.value[1] !== 0 && state.ranges[1][state.value[1]]}
                            {state.value[2] !== 0 && state.ranges[2][state.value[2]]}
                            {state.value[3] !== 0 && state.ranges[3][state.value[3]]}
                        </View>

                    }
                </View>
            </Picker>
        </View>
    )
}

转载请注明出处或者链接地址:https://www.qianduange.cn//article/14282.html
标签
taro
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!