今天的任务是根据antd-mobile的官方文档--IndexBar 序列实现城市列表,如下图
技术栈及版本:
"antd-mobile": "^5.31.1",
"axios": "^1.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.1.1",
"react-router-dom": "^6.14.1",
此时接收到的数据格式
{
"label": "北京",
"value": "AREA|88cff55c-aaa4-e2e0",
"pinyin": "beijing",
"short": "bj"
},
{
"label": "广州",
"value": "AREA|e4940177-c04c-383d",
"pinyin": "guangzhou",
"short": "gz"
},
{
"label": "上海",
"value": "AREA|dbf46d32-7e76-1196",
"pinyin": "shanghai",
"short": "sh"
},
{
"label": "深圳",
"value": "AREA|a6649a11-be98-b150",
"pinyin": "shenzhen",
"short": "sz"
}
]
当前的需求是将获取到的数据进行格式分组,再进行渲染。
接收到的city数据中含有每个城市的拼音和首字母缩写,我们可以先使用localeCompare()将其先排个序。
创建一个数组list长度26,且每个对象含有title元素,分别存放字母。最后将排序好的数组city与list进行对比,当首字母相同与title相同,push到数组中。
参考代码
function preList(area) {
//先排序
let arealist = area.sort((a, b) => a['pinyin'].localeCompare(b['pinyin']))
//创建总排序
const charCodeOfA = 'A'.charCodeAt(0);
let list =
Array(26)
.fill('')
.map((_, i) => ({
title: String.fromCharCode(charCodeOfA + i),
city: [],
}));
//根据首字母分组
arealist.forEach(item => {
let Ying = item.short.slice(0, 1).toUpperCase()
for (let i in list) {
if (Ying === list[i].title) {
list[i].city.push(item)
}
}
});
// console.log(list);
return list
}
export default preList
最后渲染列表
render() {
return (<div style={{ height: window.innerHeight }}>
<IndexBar>
{this.state.citylist.map(group => {
const { title, city } = group;
return (<IndexBar.Panel index={title.slice(0, 1)} title={title} key={title}>
<List>
{city.map((item, index) => (<List.Item key={index} onClick={this.changeCity.bind(this, item)}>{item.label}</List.Item>))}
</List>
</IndexBar.Panel>);
})}
</IndexBar>
</div>);
}