天天看點

好客租房150-切換城市

1給城市清單項綁定點選事件

2判斷是不是北上廣深資料

3有房源資料 存到本地緩存中

import React from 'react'
import axios from 'axios'
//導入axios
//導入navBar元件
import { NavBar, Icon,Toast } 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

// 有房源的城市
const HOUSE_CITY = ['北京', '上海', '廣州', '深圳']
class cityList extends React.Component {
    constructor(props){
        super(props)
        this.state= {
            cityList: [],
            cityIndex: [],
            activeIndex:0
        }
        //建立ref對象
        this.cityListComponent=React.createRef()
    }
  changeCity(curcity){
        console.log(curcity)
    }
  //處理封裝字母索引的方法
  formDataCityIndex = (letter) => {
    switch (letter) {
      case '#':
        return '目前定位'
      case 'hot':
        return '熱門城市'
      default:
        return letter.toUpperCase()
    }
  }
  async componentDidMount() {
    await this.getCityList()

        //提前計算每一行的高度
        //注意這個方法的時候 保證list元件有資料了
        this.cityListComponent.current.measureAllRows(0)
  }
    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)
        }
      }
  // 渲染每一行資料的渲染函數
  // 函數的傳回值就表示最終渲染在頁面中的内容
  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>
        {/* 上海 */}
        {cityList[letter].map((item) => (
          <div className="name" onClick={()=>this.changeCity(item)} 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={[
          //  
          //    key="0"
          //    type="search"
          //    style={{ marginRight: '16px' }}
          //  />,
          //  ,
          // ]}
        >
          城市選擇
        </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      

運作結果