一.城市选择界面
分为三个部分去封装,第一个是头部导航,第二个是侧边导航列表,第三个是城市列表显示
- 顶部导航由于在之后的地图找房列表中也会用到,便封装一个自己的NavBar组件,将文字和字体图标变成参数传入自定义的NavBar组件,实现组件复用。
- 由于城市列表可能很长,所以列表加载可能会导致页面卡顿,滚动不流畅等性能问题,所以使用react-virtualized中的List组件,使它每次只加载可视区域的数据,AutoSizer组件是渲染自动长度
- onRowsRendered,如果此时列表索引不等于最顶部的列表索引,即刻更新列表内容
// 滚动列表触发 onRowsRendered = ({ startIndex }) => { if (this.state.activeIndex !== startIndex) { console.log(startIndex); this.setState({ activeIndex: startIndex }) } }
- getRowHeight动态获取每行的行高
-
rowRenderer渲染列表项
// 渲染列表项 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-item"> <div className="title">{this.formatLetter(letter)}</div>{/*渲染当前城市/热门城市/城市首字母*/} { cityList[letter].map((item) => <div onClick={() => this.changeCity(item)} key={item.value} className="name">{item.label}</div>) } {/*绑定点击事件,改变当前定位*/} </div> ); }
- formatLetter
formatLetter(letter, first) { switch (letter) { case 'hot': return first ? '热' : '热门城市'; case '#': return first ? '当' : '当前城市'; default: return letter.toUpperCase(); } }
3.右侧导航列表索引renderCityIndex获取到索引数组CityIndex,遍历CityIndex,渲染索引列表,在state中添加状态 activeIndex,用来指定当前高亮的索引。在遍历cityIndex时,添加当前字母索引是否是高亮。调用List组件的 scrollToRow方法,让List组件滚动到指定行
// 渲染右侧索引 renderCityIndex = () => { const { cityIndex, activeIndex } = this.state; //遍历CityIndex,渲染索引列表 return cityIndex.map((item, index) => { return ( <li key={item} className="city-index-item" onClick={() => { console.log(this.listRef); //点击事件 //调用List组件的 scrollToRow方法,让List组件滚动到指定行 this.listRef.current.scrollToRow(index) }} > <span className={activeIndex === index ? 'index-active' : ''}> {this.formatLetter(item, true)} </span> {/*添加当前字母索引是否是高亮*/} </li> ) }) }