好客租房149-渲染右侧索引列表(点击索引指定该索引城市)

简介: 好客租房149-渲染右侧索引列表(点击索引指定该索引城市)

1给索引列表绑定点击事件

2在点击事件中 通过index获取到当前项索引号

3调用list组件的scrollToRow方法 让list组件滚动到指定行

4设置list的scrollToAlignment为start对准

import React from 'react'
import axios from 'axios'
//导入axios
//导入navBar组件
import { NavBar, Icon } from 'antd-mobile'
import './index.scss'
import { getCurrentCity } from '../../utils'
//导入react-virtualized组件
import { List, AutoSizer } from 'react-virtualized'
// 数据格式化的方法
// 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()
  return {
    cityList,
    cityIndex,
  }
}
// 列表数据的数据源
const list = Array(100).fill('react-virtualized')
const TITLE_HEIGHT = 36
const NAME_HEIGHT = 50
class cityList extends React.Component {
    constructor(props){
        super(props)
        this.state= {
            cityList: [],
            cityIndex: [],
            activeIndex:0
        }
        //创建ref对象
        this.cityListComponent=React.createRef()
    }
  //处理封装字母索引的方法
  formDataCityIndex = (letter) => {
    switch (letter) {
      case '#':
        return '当前定位'
      case 'hot':
        return '热门城市'
      default:
        return letter.toUpperCase()
    }
  }
  async componentDidMount() {
    await this.getCityList()
        //提前计算每一行的高度
        //注意这个方法的时候 保证list组件有数据了
        this.cityListComponent.current.measureAllRows(0)
  }
  // 渲染每一行数据的渲染函数
  // 函数的返回值就表示最终渲染在页面中的内容
  rowRenderer({
    key, // Unique key within array of rows
    index, // 索引号
    isScrolling, // 当前项是否正在滚动中
    isVisible, // 当前项在 List 中是可见的
    style, // 注意:重点属性,一定要给每一个行数据添加该样式!作用:指定每一行的位置
  }) {
    //获取每一行的索引号
    const { cityIndex, cityList } = this.state
    const letter = cityIndex[index]
    //指定城市列表数据
    return (
      <div key={key} style={style} className="city">
        <div className="title">{this.formDataCityIndex(letter)}</div>
        {/* <div className="name">上海</div> */}
        {cityList[letter].map((item) => (
          <div className="name" key={item.value}>
            {item.label}
          </div>
        ))}
      </div>
    )
  }
  async getCityList() {
    const res = await axios.get('http://localhost:8080/area/city?level=1')
    console.log(res, 'resss')
    const { cityList, cityIndex } = formatCityData(res.data.body)
    console.log(cityList, cityIndex)
    const hotRes = await axios.get('http://localhost:8080/area/hot')
    console.log(hotRes, 'hotRes')
    cityList['hot'] = hotRes.data.body
    cityIndex.unshift('hot')
    console.log(cityList, cityIndex, 'hotList')
    //获取当前定位城市
    const curcity = await getCurrentCity()
    cityList['#'] = [curcity]
    cityIndex.unshift('#')
    this.setState({
      cityList,
      cityIndex,
    })
  }
     // 封装渲染右侧索引列表的方法
  renderCityIndex() {
    // 获取到 cityIndex,并遍历其,实现渲染
    const { cityIndex, activeIndex } = this.state
    return cityIndex.map((item, index) => (
      <li className="city-index-item" key={item} onClick={()=>{
          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
      })
    }
  }
  getRowHeight({ index }) {
    // 索引标题高度 + 城市数量 * 城市名称的高度
    // TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
    const { cityList, cityIndex } = this.state
    return TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
  }
  render() {
    return (
      <div className="citylist">
        <NavBar
          className="navbar"
          mode="light"
          icon={<i className="iconfont icon-back" />}
          onLeftClick={() => this.props.histoty.push.go(-1)}
          // 导航栏右边内容
          // rightContent={[
          //  <Icon
          //    key="0"
          //    type="search"
          //    style={{ marginRight: '16px' }}
          //  />,
          //  <Icon key="1" type="ellipsis" />,
          // ]}
        >
          城市选择
        </NavBar>
        {/* 城市列表 */}
        <AutoSizer>
          {({ width, height }) => (
            <List
                            ref={this.cityListComponent}
              width={width}
              height={height}
              rowCount={this.state.cityIndex.length}
              rowHeight={this.getRowHeight.bind(this)}
              rowRenderer={this.rowRenderer.bind(this)}
                            onRowsRendered={this.onRowsRendered}
            />
          )}
        </AutoSizer>
                  {/* 右侧索引列表 */}
        {/* 
          1 封装 renderCityIndex 方法,用来渲染城市索引列表。
          2 在方法中,获取到索引数组 cityIndex ,遍历 cityIndex ,渲染索引列表。
          3 将索引 hot 替换为 热。
          4 在 state 中添加状态 activeIndex ,指定当前高亮的索引。
          5 在遍历 cityIndex 时,添加当前字母索引是否高亮的判断条件。
        */}
        <ul className="city-index">{this.renderCityIndex()}</ul>
      </div>
    )
  }
}
export default cityList

运行结果

图片.png

相关文章
|
SQL Oracle 关系型数据库
Flink的表值函数(Table-Valued Function,TVF)是一种返回值是一张表的函数
【2月更文挑战第17天】Flink的表值函数(Table-Valued Function,TVF)是一种返回值是一张表的函数
314 1
|
Python
Matplotlib 教程 之 Matplotlib 绘制多图 2
subplot()` 需要手动指定位置参数,而 `subplots()` 可以一次性生成多个子图,只需调用生成对象的 `ax`。示例代码展示了如何在一个 2x2 的网格中绘制四个不同的子图,并为每个子图设置了标题,最后还添加了一个总标题 &quot;Baidu subplot Test&quot;。
137 0
|
网络协议 Java 应用服务中间件
springboot服务端接口外网远程调试,并实现HTTP服务监听(一)
springboot服务端接口外网远程调试,并实现HTTP服务监听(一)
255 0
|
Java
Java NIO 中的 Buffer 缓冲区详解(下)
Java NIO 中的 Buffer 缓冲区详解
297 0
Java NIO 中的 Buffer 缓冲区详解(下)
|
SQL 存储 cobar
分库分布的几件小事(一)数据库如何拆分
为何要分库分表、分库分表的方式
|
存储 机器学习/深度学习 缓存
蚂蚁智能化中台:驱动业务高速发展的飞轮
在金融科技行业,智能中台已经成为提升业务创新能力的重要支撑,正不断以数据资产驱动业务创新,全方位、多角度地重塑产业链。
762 0
蚂蚁智能化中台:驱动业务高速发展的飞轮
Yii2.0的路由是什么?底层原理是什么?
Yii2.0的路由是什么?底层原理是什么?
280 0
栈的实际应用-后缀表达式与顺序表思考题
栈的实际应用-后缀表达式与顺序表思考题
栈的实际应用-后缀表达式与顺序表思考题
|
消息中间件 存储 canal
赢了面子,输了里子,缓存就是个面子
使用缓存来加速应用程序的访问速度,是几乎所有高性能系统都会采用的方法。 但缓存真的那么好吗?架构师在构建高性能系统时,是不是必须增加缓存组件?缓存是不是多多益善? 《一代宗师》里本山大叔说过这样的一段话: “一门里,有人当面子,就得有人当里子。面子不能沾一点儿灰尘。流了血,里子得收着,收不住,漏到了面子上,就是毁派灭门的大事。”
367 0
赢了面子,输了里子,缓存就是个面子
|
数据安全/隐私保护
多机免密登录自动化脚本
多机免密登录自动化脚本
264 0