将获取城市数据按ABCD顺序排列

在这里插入图片描述

  • 后台返回的数据 (数组返回所有 城市数据)
    [{"label":"北京","value":"AREA|88cff55c-aaa4-e2e0","pinyin":"beijing","short":"bj"},{"label":"安庆","value":"AREA|b4e8be1a-2de2-e039","pinyin":"anqing","short":"aq"},{"label":"南宁","value":"AREA|2bc437ca-b3d2-5c3c","pinyin":"nanning","short":"nn"},{"label":"长沙","value":"AREA|98b03413-6f84-c263","pinyin":"changsha","short":"cs"},{"label":"武汉","value":"AREA|27e414ce-a7e1-fd99","pinyin":"wuhan","short":"wh"},{"label":"重庆","value":"AREA|df130a14-79a9-a2ca","pinyin":"zhongqing","short":"zq"},{"label":"青岛","value":"AREA|0941e83b-fe11-b392","pinyin":"qingdao","short":"qd"},{"label":"郑州","value":"AREA|37d79dc2-f02d-0023","pinyin":"zhengzhou","short":"zz"},{"label":"沈阳","value":"AREA|d7233472-6b89-e7e5","pinyin":"shenyang","short":"sy"},{"label":"佛山","value":"AREA|0ee75d32-8a95-3f73","pinyin":"foshan","short":"fs"},{"label":"成都","value":"AREA|27a05931-1701-4e74","pinyin":"chengdu","short":"cd"},{"label":"杭州","value":"AREA|19b39d4f-8a36-d6f8","pinyin":"hangzhou","short":"hz"},{"label":"西安","value":"AREA|57c882ca-7b1b-afcc","pinyin":"xian","short":"xa"},{"label":"广州","value":"AREA|e4940177-c04c-383d","pinyin":"guangzhou","short":"gz"},{"label":"廊坊","value":"AREA|0233f220-a4e2-8a00","pinyin":"langfang","short":"lf"},{"label":"济南","value":"AREA|8b1d0441-81ab-e9cb","pinyin":"jinan","short":"jn"},{"label":"徐州","value":"AREA|de160fec-9197-60e4","pinyin":"xuzhou","short":"xz"},{"label":"南京","value":"AREA|93dec481-bd0b-577e","pinyin":"nanjing","short":"nj"},{"label":"合肥","value":"AREA|a7979a07-fffb-7afc","pinyin":"hefei","short":"hf"},{"label":"兰州","value":"AREA|b7b0889e-fb72-9fbc","pinyin":"lanzhou","short":"lz"},{"label":"惠州","value":"AREA|a4c6e115-a283-d137","pinyin":"huizhou","short":"hz"},{"label":"福州","value":"AREA|c29923ed-7257-143f","pinyin":"fuzhou","short":"fz"},{"label":"盐城","value":"AREA|28cbc063-20be-4abd","pinyin":"yancheng","short":"yc"},{"label":"镇江","value":"AREA|fc2a4bb5-76ee-486e","pinyin":"zhenjiang","short":"zj"},{"label":"咸阳","value":"AREA|884366b8-accf-ad7f","pinyin":"xianyang","short":"xy"},{"label":"长春","value":"AREA|5f14a39a-fcf5-09fb","pinyin":"changchun","short":"cc"},{"label":"哈尔滨","value":"AREA|1374672e-51da-ed2c","pinyin":"haerbin","short":"heb"},{"label":"太原","value":"AREA|6319a60d-d9e0-3a48","pinyin":"taiyuan","short":"ty"},{"label":"常州","value":"AREA|b83bf8cb-7934-8789","pinyin":"changzhou","short":"cz"},{"label":"江门","value":"AREA|d41c669e-bb9a-5e26","pinyin":"jiangmen","short":"jm"},{"label":"潍坊","value":"AREA|d5620763-a8ea-f2c2","pinyin":"weifang","short":"wf"},{"label":"淮安","value":"AREA|1f5da761-3fa2-07b1","pinyin":"huaian","short":"ha"},{"label":"泉州","value":"AREA|14715419-13bd-3924","pinyin":"quanzhou","short":"qz"},{"label":"清远","value":"AREA|98f06ebc-edf2-60ee","pinyin":"qingyuan","short":"qy"},{"label":"威海","value":"AREA|c2f7b36d-2c63-8a91","pinyin":"weihai","short":"wh"},{"label":"呼和浩特","value":"AREA|de3755d0-08b0-7cf0","pinyin":"huhehaote","short":"hhht"},{"label":"石家庄","value":"AREA|da444e4d-5adb-297a","pinyin":"shijiazhuang","short":"sjz"},{"label":"烟台","value":"AREA|ca3f7c2f-0587-605f","pinyin":"yantai","short":"yt"},{"label":"深圳","value":"AREA|a6649a11-be98-b150","pinyin":"shenzhen","short":"sz"},{"label":"天津","value":"AREA|c633fbe8-f88d-a1cd","pinyin":"tianjin","short":"tj"},{"label":"吉林","value":"AREA|7078ebcc-f436-68a0","pinyin":"jilin","short":"jl"},{"label":"银川","value":"AREA|10a55ad6-accd-51fe","pinyin":"yinchuan","short":"yc"},{"label":"上海","value":"AREA|dbf46d32-7e76-1196","pinyin":"shanghai","short":"sh"},{"label":"常德","value":"AREA|8b5c9a5f-77f4-4a6d","pinyin":"changde","short":"cd"},{"label":"赣州","value":"AREA|c143cee7-a4c3-88e3","pinyin":"ganzhou","short":"gz"},{"label":"岳阳","value":"AREA|ddb3411b-1d6d-56b2","pinyin":"yueyang","short":"yy"},{"label":"株洲","value":"AREA|f6be9464-00f8-1227","pinyin":"zhuzhou","short":"zz"},{"label":"马鞍山","value":"AREA|17ced06d-f15e-70f1","pinyin":"maanshan","short":"mas"},{"label":"芜湖","value":"AREA|83923400-e1c0-a3e2","pinyin":"wuhu","short":"wh"},{"label":"南通","value":"AREA|ee2267cd-2782-2f00","pinyin":"nantong","short":"nt"},{"label":"厦门","value":"AREA|5bc88487-f57a-3240","pinyin":"shamen","short":"sm"},{"label":"九江","value":"AREA|ace0000c-a15a-c549","pinyin":"jiujiang","short":"jj"},{"label":"吉安","value":"AREA|acb6430b-dfe3-0e5d","pinyin":"jian","short":"ja"},{"label":"南昌","value":"AREA|316343de-7862-e7d1","pinyin":"nanchang","short":"nc"},{"label":"淄博","value":"AREA|570ce3fe-3a5c-ed33","pinyin":"zibo","short":"zb"},{"label":"苏州","value":"AREA|d15bd52e-01ae-83b6","pinyin":"suzhou","short":"sz"},{"label":"上饶","value":"AREA|1a32fa69-2523-0c3f","pinyin":"shangrao","short":"sr"},{"label":"临沂","value":"AREA|5171322e-76ad-cec6","pinyin":"linyi","short":"ly"},{"label":"宝鸡","value":"AREA|d67f3282-dfc6-a687","pinyin":"baoji","short":"bj"},{"label":"大连","value":"AREA|35a9039a-f80b-8038","pinyin":"dalian","short":"dl"},{"label":"汉中","value":"AREA|9e6e8dba-8a7e-45df","pinyin":"hanzhong","short":"hz"},{"label":"达州","value":"AREA|d200295a-7aca-8eaa","pinyin":"dazhou","short":"dz"},{"label":"凉山","value":"AREA|3e0f0522-92fa-a8f5","pinyin":"liangshan","short":"ls"},{"label":"漳州","value":"AREA|8ff28dd0-b105-60d7","pinyin":"zhangzhou","short":"zz"},{"label":"绵阳","value":"AREA|36262553-3ba2-117c","pinyin":"mianyang","short":"my"},{"label":"唐山","value":"AREA|473deed8-3741-e1f8","pinyin":"tangshan","short":"ts"},{"label":"东莞","value":"AREA|df4995a8-a691-8898","pinyin":"dongguan","short":"dg"},{"label":"南充","value":"AREA|860700ca-69a5-22d8","pinyin":"nanchong","short":"nc"},{"label":"张家口","value":"AREA|c03617ff-d6ef-90c2","pinyin":"zhangjiakou","short":"zjk"},{"label":"海口","value":"AREA|e4f7245e-1773-3170","pinyin":"haikou","short":"hk"},{"label":"襄阳","value":"AREA|a8398f44-4c1d-eba4","pinyin":"xiangyang","short":"xy"},{"label":"三亚","value":"AREA|1466e8f3-6fc2-7000","pinyin":"sanya","short":"sy"},{"label":"无锡","value":"AREA|c78c958e-9269-d831","pinyin":"wuxi","short":"wx"},{"label":"湛江","value":"AREA|5da079fb-f421-4108","pinyin":"zhanjiang","short":"zj"},{"label":"昆明","value":"AREA|e66fe36b-48d3-598d","pinyin":"kunming","short":"km"},{"label":"开封","value":"AREA|aace77fb-3a22-fc40","pinyin":"kaifeng","short":"kf"},{"label":"洛阳","value":"AREA|cd295c34-0609-8454","pinyin":"luoyang","short":"ly"},{"label":"湖州","value":"AREA|8a85acd3-bd18-51de","pinyin":"huzhou","short":"hz"},{"label":"嘉兴","value":"AREA|18eff40f-35ca-f2cf","pinyin":"jiaxing","short":"jx"},{"label":"丹东","value":"AREA|2124ed8d-33e7-a88f","pinyin":"dandong","short":"dd"},{"label":"贵阳","value":"AREA|efdb858e-9758-b04d","pinyin":"guiyang","short":"gy"},{"label":"新乡","value":"AREA|b1dd9469-8757-dd35","pinyin":"xinxiang","short":"xx"},{"label":"宁波","value":"AREA|efd4aaad-e73f-3843","pinyin":"ningbo","short":"nb"},{"label":"许昌","value":"AREA|53fd4de5-6b11-5bc9","pinyin":"xuchang","short":"xc"},{"label":"宜昌","value":"AREA|b6816d6d-b988-da07","pinyin":"yichang","short":"yc"},{"label":"北海","value":"AREA|7d0c1398-df56-c4e8","pinyin":"beihai","short":"bh"},{"label":"绍兴","value":"AREA|30cc945e-2ff7-69cf","pinyin":"shaoxing","short":"sx"},{"label":"桂林","value":"AREA|7a8db7e0-ba57-ba5e","pinyin":"guilin","short":"gl"},{"label":"柳州","value":"AREA|55acc2ee-5add-917e","pinyin":"liuzhou","short":"lz"},{"label":"台州","value":"AREA|5f9100f6-9259-a7aa","pinyin":"taizhou","short":"tz"},{"label":"珠海","value":"AREA|515b6047-b0ed-edf2","pinyin":"zhuhai","short":"zh"},{"label":"温州","value":"AREA|29d27e65-390c-f15e","pinyin":"wenzhou","short":"wz"}]
    
  • 前台修改为所需数据格式
    const formatCityData = list => {
    	  const cityList = {}
    	  // 1 遍历list数组
    	  list.forEach(item => {
    	    // 2 获取每一个城市的首字母
    	    const first = item.short.substr(0, 1)
    	    // 3 判断 cityList 中是否有该分类
    	    if (cityList[first]) {
    	      // 4 如果有,直接往该分类中push数据
    	      // cityList[first] => [{}, {}]
    	      cityList[first].push(item)
    	    } else {
    	      // 5 如果没有,就先创建一个数组,然后,把当前城市信息添加到数组中
    	      cityList[first] = [item]
    	    }
    	  })
    
    // 获取索引数据
    const cityIndex = Object.keys(cityList).sort()
    
    return {
    cityList,
    cityIndex
    }
    

}
```
cityList数据为

	{
	"b": [{
		"label": "北京",
		"value": "AREA|88cff55c-aaa4-e2e0",
		"pinyin": "beijing",
		"short": "bj"
	}, {
		"label": "宝鸡",
		"value": "AREA|d67f3282-dfc6-a687",
		"pinyin": "baoji",
		"short": "bj"
	}, {
		"label": "北海",
		"value": "AREA|7d0c1398-df56-c4e8",
		"pinyin": "beihai",
		"short": "bh"
	}],
	"a": [{
		"label": "安庆",
		"value": "AREA|b4e8be1a-2de2-e039",
		"pinyin": "anqing",
		"short": "aq"
	}]
}

cityIndex数据为

["a","b","c","d","f","g","h","j","k","l","m","n","q","s","t","w","x","y","z"]

完整的react代码

import React from 'react'

import axios from 'axios'
import { Toast } from 'antd-mobile'

// 导入 List 组件
import { List, AutoSizer } from 'react-virtualized'

// 导入 utils 中获取当前定位城市的方法
import { getCurrentCity } from '../../utils'

// 导入 NavHeader 组件
import NavHeader from '../../components/NavHeader'

import './index.scss'

// 导入 CSSModules 的样式文件
// import styles from './index.module.css'
// console.log(styles)

// 数据格式化的方法
// list: [{}, {}]
const formatCityData = list => {
  const cityList = {}
  // const cityIndex = []

  // 1 遍历list数组
  list.forEach(item => {
    // 2 获取每一个城市的首字母
    const first = item.short.substr(0, 1)
    // 3 判断 cityList 中是否有该分类
    if (cityList[first]) {
      // 4 如果有,直接往该分类中push数据
      // cityList[first] => [{}, {}]
      cityList[first].push(item)
    } else {
      // 5 如果没有,就先创建一个数组,然后,把当前城市信息添加到数组中
      cityList[first] = [item]
    }
  })

  // 获取索引数据
  const cityIndex = Object.keys(cityList).sort()
  console.log(JSON.stringify(cityList))
  console.log(JSON.stringify(cityIndex))
  return {
    cityList,
    cityIndex
  }
}

// 索引(A、B等)的高度
const TITLE_HEIGHT = 36
// 每个城市名称的高度
const NAME_HEIGHT = 50

// 封装处理字母索引的方法
const formatCityIndex = letter => {
  switch (letter) {
    case '#':
      return '当前定位'
    case 'hot':
      return '热门城市'
    default:
      return letter.toUpperCase()
  }
}

// 有房源的城市
const HOUSE_CITY = ['北京', '上海', '广州', '深圳']

export default class CityList extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      cityList: {},
      cityIndex: [],
      // 指定右侧字母索引列表高亮的索引号
      activeIndex: 0
    }

    // 创建ref对象
    this.cityListComponent = React.createRef()
  }

  async componentDidMount() {
    await this.getCityList()

    // 调用 measureAllRows,提前计算 List 中每一行的高度,实现 scrollToRow 的精确跳转
    this.cityListComponent.current.measureAllRows()
  }

  // 获取城市列表数据的方法
  async getCityList() {
    const res = await axios.get('http://localhost:8080/area/city?level=1')
    const { cityList, cityIndex } = formatCityData(res.data.body)
    console.log('城市',JSON.stringify(res.data.body))

    // 获取热门城市数据
    const hotRes = await axios.get('http://localhost:8080/area/hot')
    cityList['hot'] = hotRes.data.body
    cityIndex.unshift('hot')

    // 获取当前定位城市
    const curCity = await getCurrentCity()
    cityList['#'] = [curCity]
    cityIndex.unshift('#')

    // console.log(cityList, cityIndex, curCity)
    this.setState({
      cityList,
      cityIndex
    })
  }

  changeCity({ label, value }) {
    if (HOUSE_CITY.indexOf(label) > -1) {
      // 有
      localStorage.setItem('hkzf_city', JSON.stringify({ label, value }))
      this.props.history.go(-1)
    } else {
      Toast.info('该城市暂无房源数据', 1, null, false)
    }
  }

  // List组件渲染每一行的方法:
  rowRenderer = ({
    key, // Unique key within array of rows
    index, // 索引号
    isScrolling, // 当前项是否正在滚动中
    isVisible, // 当前项在 List 中是可见的
    style // 注意:重点属性,一定要给每一个行数据添加该样式!作用:指定每一行的位置
  }) => {
    // 获取每一行的字母索引
    const { cityIndex, cityList } = this.state
    const letter = cityIndex[index]

    // 获取指定字母索引下的城市列表数据
    // console.log(cityList[letter])

    return (
      <div key={key} style={style} className="city">
        <div className="title">{formatCityIndex(letter)}</div>
        {cityList[letter].map(item => (
          <div
            className="name"
            key={item.value}
            onClick={() => this.changeCity(item)}
          >
            {item.label}
          </div>
        ))}
      </div>
    )
  }

  // 创建动态计算每一行高度的方法
  getRowHeight = ({ index }) => {
    // 索引标题高度 + 城市数量 * 城市名称的高度
    // TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
    const { cityList, cityIndex } = this.state
    return TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
  }

  // 封装渲染右侧索引列表的方法
  renderCityIndex() {
    // 获取到 cityIndex,并遍历其,实现渲染
    const { cityIndex, activeIndex } = this.state
    return cityIndex.map((item, index) => (
      <li
        className="city-index-item"
        key={item}
        onClick={() => {
          // console.log('当前索引号:', index)
          this.cityListComponent.current.scrollToRow(index)
        }}
      >
        <span className={activeIndex === index ? 'index-active' : ''}>
          {item === 'hot' ? '热' : item.toUpperCase()}
        </span>
      </li>
    ))
  }

  // 用于获取List组件中渲染行的信息
  onRowsRendered = ({ startIndex }) => {
    // console.log('startIndex:', startIndex)
    if (this.state.activeIndex !== startIndex) {
      this.setState({
        activeIndex: startIndex
      })
    }
  }

  render() {
    return (
      <div className="citylist">
        {/* 顶部导航栏 */}
        <NavHeader>城市选择</NavHeader>

        {/* 城市列表 */}
        <AutoSizer>
          {({ width, height }) => (
            <List
              ref={this.cityListComponent}
              width={width}
              height={height}
              rowCount={this.state.cityIndex.length}
              rowHeight={this.getRowHeight}
              rowRenderer={this.rowRenderer}
              onRowsRendered={this.onRowsRendered}
              scrollToAlignment="start"
            />
          )}
        </AutoSizer>

        {/* 右侧索引列表 */}
        <ul className="city-index">{this.renderCityIndex()}</ul>
      </div>
    )
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值