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