Picker 多列选择器实现省市区联动

在这里插入图片描述

import React, { useState, useEffect } from 'react';
import { View, Picker } from '@tarojs/components';
import BaseInfo from '../../services/BaseInfo';

// const DEFAULT_ITEM = {
//     value: 0,
//     label: '全部',
// };

const AreaSelect = ({ province, city, county, className, onChange, allowUncertain = true }) => {
    const [areaTree, setAreaTree] = useState([]);
    const [cityArr, setCityArr] = useState([[allowUncertain ? '待确定' : ''], [''], ['']]);
    const [multiIndex, setMultiIndex] = useState([0, 0, 0]);
    const [areaText, setAreaText] = useState('');
    useEffect(() => {
        const initArea = ret => {
            const tree = [...ret];
            let provinces = [];
            let cities = [];
            let counties = [];
            const tempMultiIndex = [0, 0, 0];
            const cityInfo = {
                province_name: '',
                city_name: '',
                county_name: '',
            };
            tree.forEach((item, key) => {
                provinces.push(item.label);
                if (province === item.value) {
                    tempMultiIndex[0] = key;
                    cityInfo.province_name = item.label;
                }
            });
            provinces = tree?.map(v => v?.label);
            if (!province) {
                setMultiIndex([0, 0, 0]);
                setCityArr([provinces, [''], ['']]);
                if (province === 0) {
                    setAreaText(allowUncertain ? '待确定' : '');
                }
                return;
            }
            if ([2280, 1042, 2818, 568, 3521].includes(province)) {
                // 四个直辖市 + 澳门
                tempMultiIndex[1] = 0;
                cities.push(tree[tempMultiIndex[0]].label);
                // cities.unshift(DEFAULT_ITEM);
                tree[tempMultiIndex[0]].children.forEach((item, key) => {
                    counties.push(item.label);
                    if (city === item.value) {
                        tempMultiIndex[2] = key;
                        cityInfo.province_name = item.label;
                    }
                });
                // counties.unshift(DEFAULT_ITEM);
            } else {
                tree[tempMultiIndex[0]].children.forEach(item => {
                    cities.push(item.label);
                });
                cities = tree[tempMultiIndex[0]].children?.map(v => v?.label);
                // cities.unshift(DEFAULT_ITEM);
                tree[tempMultiIndex[0]].children[tempMultiIndex[1]].children.forEach(item => {
                    counties.push(item.label);
                });
                // counties.unshift(DEFAULT_ITEM);
                tree[tempMultiIndex[0]].children.forEach((item, key) => {
                    if (city === item.value) {
                        tempMultiIndex[1] = key;
                        cityInfo.city_name = item.label;
                    }
                });

                if (!tree[tempMultiIndex[0]].children[tempMultiIndex[1]].children) {
                    // eslint-disable-next-line no-param-reassign
                    tree[tempMultiIndex[0]].children[tempMultiIndex[1]].children = [];
                }
                counties = tree[tempMultiIndex[0]].children[tempMultiIndex[1]].children?.map(
                    v => v?.label,
                );
                tree[tempMultiIndex[0]].children[tempMultiIndex[1]].children.forEach(
                    (item, key) => {
                        if (county === item.value) {
                            tempMultiIndex[2] = key;
                            cityInfo.county_name = item.label;
                        }
                    },
                );
            }
            const arr = [provinces, cities, counties];
            let areaText = '';
            setMultiIndex(tempMultiIndex);
            setCityArr(arr);
            if (arr[2][tempMultiIndex[2]] !== undefined) {
                areaText = `${arr[0][tempMultiIndex[0]]}/${arr[1][tempMultiIndex[1]]}/${
                    arr[2][tempMultiIndex[2]]
                }`;
                // areaText = `${cityInfo?.province_name}/${cityInfo?.city_name}/${cityInfo?.county_name}`;
            } else {
                areaText = `${arr[0][tempMultiIndex[0]]}/${arr[1][tempMultiIndex[1]]}`;
                // areaText = `${cityInfo?.province_name}/${cityInfo?.city_name}`;
            }
            // console.log('counties', counties);
            // console.log(777, arr, tempMultiIndex);
            // console.log(999, cityInfo, areaText);

            setAreaText(areaText);
        };

        BaseInfo.fetchArea().then(res => {
            if (res.XCmdrCode === 0) {
                res.XCmdrResult.unshift({
                    id: 0,
                    label: '待确定',
                });
                setAreaTree(res.XCmdrResult);
                initArea(res.XCmdrResult);
            }
        });
    }, [allowUncertain, city, county, province]);

    const handleColumnChange = e => {
        const { column, value } = e.detail;
        const cities = [];
        const counties = [];
        const tempMultiIndex = [...multiIndex];
        tempMultiIndex[column] = value;
        switch (column) {
            case 0:
                // 省份切换
                // 对待确定特殊处理
                if (value === 0) {
                    setMultiIndex([0, 0, 0]);
                    setCityArr(c => [c[0], [''], ['']]);
                    return;
                }
                if (!areaTree[value].children[0].children) {
                    // 直辖市
                    cities.push(areaTree[value].label);
                    areaTree[value].children.forEach(item => {
                        counties.push(item.label);
                    });
                } else {
                    areaTree[value].children.forEach(item => {
                        cities.push(item.label);
                    });
                    areaTree[value].children[0].children.forEach(item => {
                        counties.push(item.label);
                    });
                }
                setMultiIndex([value, 0, 0]);
                setCityArr(c => [c[0], cities, counties]);
                break;
            case 1:
                tempMultiIndex[2] = 0;
                if (areaTree[tempMultiIndex[0]].children[tempMultiIndex[1]].children !== null) {
                    areaTree[tempMultiIndex[0]].children[tempMultiIndex[1]].children.forEach(
                        item => {
                            counties.push(item.label);
                        },
                    );
                }
                setMultiIndex(tempMultiIndex);
                setCityArr(c => [c[0], c[1], counties]);
                break;
            case 2:
                setMultiIndex(tempMultiIndex);
                break;
            default:
                break;
        }
    };

    const handleChange = e => {
        const { value } = e.detail;
        let choosedCity = '';
        let text = '';
        let cityInfo = {
            province_id: '',
            city_id: '',
            county_id: '',
        };
        if (value[0] === 0) {
            setAreaText(allowUncertain ? '待确定' : '');
            cityInfo = {
                province_id: 0,
                city_id: 0,
                county_id: 0,
            };
            onChange(0, cityInfo);
            return;
        }
        if (!areaTree[value[0]].children[value[1]].children) {
            // 直辖市
            choosedCity =
                multiIndex[2] === 0
                    ? areaTree[value[0]].children[value[1]].value
                    : areaTree[value[0]].children[value[2]].value;
            cityInfo = {
                province_id: areaTree[value[0]]?.value,
                city_id: areaTree[value[0]]?.value,
                county_id: choosedCity,
                province_name: areaTree[value[0]],
                city_name: areaTree[value[0]],
                county_name:
                    multiIndex[2] === 0
                        ? areaTree[value[0]].children[value[1]]
                        : areaTree[value[0]].children[value[2]],
            };
        } else {
            choosedCity = areaTree[value[0]].children[value[1]].children[value[2]]
                ? areaTree[value[0]].children[value[1]].children[value[2]].value
                : areaTree[value[0]].children[value[1]].value;
            cityInfo = {
                province_id: areaTree[value[0]]?.value,
                city_id: areaTree?.[value[0]]?.children[value[1]]?.value,
                county_id: choosedCity,
                province_name: areaTree[value[0]],
                city_name: areaTree?.[value[0]]?.children[value[1]],
                county_name: areaTree[value[0]].children[value[1]].children[value[2]]
                    ? areaTree[value[0]].children[value[1]].children[value[2]]
                    : areaTree[value[0]].children[value[1]],
            };
        }
        if (cityArr[2][multiIndex[2]] !== undefined) {
            text = `${cityArr[0][multiIndex[0]]}/${cityArr[1][multiIndex[1]]}/${
                cityArr[2][multiIndex[2]]
            }`;
        } else {
            text = `${cityArr[0][multiIndex[0]]}/${cityArr[1][multiIndex[1]]}`;
        }

        setAreaText(text);
        onChange(choosedCity, cityInfo);
    };

    return (
        <Picker
            mode="multiSelector"
            value={multiIndex}
            range={cityArr}
            onChange={handleChange}
            onColumnChange={handleColumnChange}
        >
            <View className={className}>{areaText || '请选择'}</View>
        </Picker>
    );
};

export default AreaSelect;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值