GITHUB 地址
基于高德数据 tsx-taro 版h5的省市区选择器
- 因为taro picker组件 mode='region' 对于h5实际不兼容,因此通过 multiSelector 进行封装
- 数据来源高德api
- 数据类似region.ts 该组件使用接口请求获取数据,可自行改为region中的数据
修改数据重点位置
const res = await getRegion();
if (res) {
const regionAllTemp = res?.data?.districts?.[0]?.districts;
...
}
演示

demo
const onReigonChange = (e, obj: TRegionObj) => {
console.log(e, obj);
};
<RegionPicker
onReigonChange={onReigonChange}
initialValues={[1, 2, 0]}
/>
组件代码
.container {
:global {
.at-list__item-content {
width: 20%;
flex: none;
}
.at-list__item-extra {
display: flex;
width: 70%;
max-width: none;
}
}
}
import { getRegion } from '@/pages/global/service';
import { Picker, View } from '@tarojs/components';
import { useAsyncEffect } from 'ahooks';
import { FC, useState } from 'react';
import { AtListItem } from 'taro-ui';
import styles from './index.module.less';
export type TRegionObj = {
regionValue: number[];
regionText?: string;
regionValObjArr: any[];
};
export type TRegionPicker = {
onReigonChange: (e: any, obj: TRegionObj) => void;
initialValues?: number[];
};
const RegionPicker: FC<TRegionPicker> = (props) => {
const { onReigonChange, initialValues = [] } = props;
const [regionAll, setRegionAll] = useState<any[]>([]);
const [regionData, setRegionData] = useState<any[]>([]);
const [regionValue, setRegionValue] = useState<any[]>(initialValues);
const [regionText, setRegionText] = useState('');
const [regionValObjArr, setRegionValObjArr] = useState<any[]>([]);
useAsyncEffect(async () => {
const res = await getRegion();
if (res) {
const regionAllTemp = res?.data?.districts?.[0]?.districts;
setRegionAll(regionAllTemp);
let range: any = [];
let temp: any = [];
for (let i = 0; i < regionAllTemp?.length; i++) {
temp.push(regionAllTemp?.[i]?.name);
}
range.push(temp);
temp = [];
for (
let i = 0;
i < regionAllTemp?.[regionValue?.[0] || 0]?.districts?.length;
i++
) {
temp.push(regionAllTemp?.[regionValue?.[0] || 0]?.districts?.[i]?.name);
}
range.push(temp);
temp = [];
for (
let i = 0;
i <
regionAllTemp?.[regionValue?.[0] || 0]?.districts?.[
regionValue?.[1] || 0
]?.districts?.length;
i++
) {
temp.push(
regionAllTemp?.[regionValue?.[0] || 0]?.districts?.[
regionValue?.[1] || 0
]?.districts[i]?.name,
);
}
range.push(temp);
setRegionData(range);
const tempObjArr = [
{
...regionAllTemp?.[regionValue?.[0] || 0],
index: regionValue?.[0] || 0,
},
{
...regionAllTemp?.[regionValue?.[0] || 0]?.districts?.[
regionValue?.[1] || 0
],
index: regionValue?.[1] || 0,
},
{
...regionAllTemp?.[regionValue?.[0] || 0]?.districts?.[
regionValue?.[1] || 0
]?.districts?.[regionValue?.[2] || 0],
index: regionValue?.[2] || 0,
},
];
setRegionValObjArr(tempObjArr);
setRegionText(
regionValue?.length > 0
? `${tempObjArr?.[0]?.name || ''} ${tempObjArr?.[1]?.name || ''} ${
tempObjArr?.[2]?.name || ''
}`
: '',
);
}
}, []);
const onColumnChange = (e) => {
let rangeTemp = regionData;
let valueTemp = regionValue;
let column = e.detail.column;
let row = e.detail.value;
valueTemp[column] = row;
switch (column) {
case 0:
let cityTemp: any = [];
let districtAndCountyTemp: any = [];
for (let i = 0; i < regionAll?.[row]?.districts?.length; i++) {
cityTemp.push(regionAll?.[row]?.districts?.[i]?.name);
}
for (
let i = 0;
i < regionAll?.[row]?.districts?.[0]?.districts?.length;
i++
) {
districtAndCountyTemp.push(
regionAll?.[row]?.districts?.[0]?.districts?.[i]?.name,
);
}
valueTemp[1] = 0;
valueTemp[2] = 0;
rangeTemp[1] = cityTemp;
rangeTemp[2] = districtAndCountyTemp;
break;
case 1:
let districtAndCountyTemp2: any = [];
for (
let i = 0;
i < regionAll?.[valueTemp?.[0]]?.districts?.[row]?.districts?.length;
i++
) {
districtAndCountyTemp2.push(
regionAll?.[valueTemp?.[0]]?.districts?.[row]?.districts?.[i]?.name,
);
}
valueTemp[2] = 0;
rangeTemp[2] = districtAndCountyTemp2;
break;
case 2:
break;
}
setRegionData(rangeTemp);
const tempObjArr = [
{ ...regionAll?.[valueTemp?.[0]], index: valueTemp?.[0] },
{
...regionAll?.[valueTemp?.[0]]?.districts?.[valueTemp?.[1]],
index: valueTemp?.[1],
},
{
...regionAll?.[valueTemp?.[0]]?.districts?.[valueTemp?.[1]]
?.districts?.[valueTemp?.[2]],
index: valueTemp?.[2],
},
];
setRegionValObjArr(tempObjArr);
setRegionValue([...valueTemp]);
};
return (
<View className={styles.container}>
<Picker
mode="multiSelector"
range={[...regionData]}
value={regionValue}
onChange={(e) => {
const tempRegionText = `${regionValObjArr?.[0]?.name || ''} ${
regionValObjArr?.[1]?.name || ''
} ${regionValObjArr?.[2]?.name || ''}`;
setRegionText(tempRegionText);
onReigonChange(e, {
regionValue: e.detail?.value,
regionText: tempRegionText,
regionValObjArr,
});
}}
onColumnChange={onColumnChange}
>
<AtListItem title="所在地" arrow="right" extraText={regionText} />
</Picker>
</View>
);
};
export default RegionPicker;