由于工作的原因,昨天的直播暂时缓一缓,今天先为工作做一个准备。
首先我城市组件支持的数据格式:
[//权限内的区域权限
{
"name": "北京市",
"items": [
{
"name": "北京市",
"items": [
{
"name": "石景山区",
},
{
"name": "怀柔区",
},
]
}
]
},
{
"name": "河北省",
"items": [
{
"name": "石家庄市",
"items": [
{
"name": "新华区",
}
]
}
]
},
{
"name": "吉林省",
"items": [
{
"name": "吉林市",
"items": [
{
"name": "船营区",
}
]
}
]
},
{
"name": "上海市",
"items": [
{
"name": "上海市",
"items": [
{
"name": "黄浦区",
}
]
}
]
}
]
今天只是先把模型弄出来,并不是最终的版本。
我使用一个 FlatList 完成下面的效果:
我要设计的这个城市选择组件支持自定义数据源,自定义宽度,自定义初次进入默认选中的省份,自定义等级,比如分三栏,也可以自定义分四栏。下面是定义选中的数组:
const [indexes, setIndexes] = useState([0, 0, 1]);
我这里默认使用三栏来举例,当时候全部封装完成以后能够根据数据来确定这个数组。
接下来看布局部分:
<View
style={{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#ccc',
marginTop: 80,
}}>
<Text>返回</Text>
<Text>选择城市</Text>
</View>
<ScrollView horizontal={true}>
<View style={{flex: 1, flexDirection: 'row', backgroundColor: '#fff'}}>
{[0, 0, 0].map((items, index) => {
return (
<FlatList
style={{
backgroundColor: `#${index + 5}0${index + 5}`,
height: '100%',
width: Dimensions.get('screen').width / 3,
}}
data={selectData(index, indexes)}
renderItem={({item, index: i}) => {
return (
<Text
onPress={() => {
setIndexes((indexes) => {
indexes[index] = i;
for (let i = index + 1; i < 3; i++) {
indexes[i] = 0;
}
return [...indexes];
});
}}
style={{
padding: 20,
backgroundColor: indexes[index] === i ? '#fff' : 'red',
marginVertical: 10,
}}>
{item?.name}
</Text>
);
}}
/>
);
})}
</View>
</ScrollView>
最重要的就是上边的 selectData 函数,这个函数就是自动选择此时应该渲染那一层:
const selectData = (index, indexes) => {
let tempData = data;
for (let i = 0; i < index; i++) {
tempData = tempData[indexes[i]].items;
}
return tempData;
};
主要是根据当前循环到的 index ,根据这个自动向数据深处寻找数据。
之所以记录这个,一个很重要的原因是以前渲染我都是从上到下,从左到右的方式进行。虽然我写的这个也的确也遵从上面的原则,但是达到了一次遍历却能做到全部渲染,而且渲染给我们感觉就是一行一行的进行。这个跟我们公司的组织架构一样,表面上看我属于某一个项目组,实际上是我还是属于某一个部门,然后再到项目组。