首先处理数据
我们渲染的内容需要每一个字母对应的数据在下面显示,并且配有右侧导航索引
首先从后台拿到数据进行处理成我们想要的数据结构
- 内容数据结构
let obj = {
a: [
{name...}内容
{name...}内容
],
b:[
{name...}内容
{name...}内容
]
....
}
- 右侧索引结构
let arr = [a, b, c...]
从后台获取热门数据添加
obj['hot'] = data
arr.unshift('hot')
然后通过百度地图API获取到当前城市再从后台验证后添加进自定义数据结构
obj['#'] = data
arr.unshift('#')
最终把处理好的数据赋值到state
渲染数据到页面中
- 这里我通过react-virtualized插件完成基本逻辑和样式,并且可视区渲染优化了性能
- 安装
yarn add react-virtualized
- 导入AutoSizer和List组件
import { List, AutoSizer } from 'react-virtualized'
<AutoSizer>{({ height, width }) => <List
// 宽度
width={width}
// 高度
height={height}
// 渲染多少条数据
rowCount={this.state.cityIndexArr.length}
// 每条数据高度 动态计算
rowHeight={this.handleHeight}
// 渲染内容
rowRenderer={this.rowRenderer}
// 滚动时拿到相关下标
onRowsRendered={this.scrollRender}
ref={this.listRef}
// 对齐方式 滚动从行开始位置对齐
scrollToAlignment='start'
/>
}</AutoSizer>
- 右侧索引通过定位到右侧
点击高亮通过三元判断添加样式
activeIndex : 0 //默认是0
<span className={activeIndex == index ? 'index-active' : ''} /> // index 遍历的索引
左右联动
- 左侧内容滚动 ——> 右侧导航索引对应高亮
List组件中有一个方法onRowsRendered,用于获取当前列表渲染的行信息。
onRowsRendered = ({startIndex }) => {
console.log(startIndex);
this.setState({
activeIndex : startIndex
})
}
- 点击右侧导航 ———> 左侧滚动到对应内容
通过ref手动调用 List 组件的 scrollToRow 方法。
this.listRef.current.scrollToRow(index)
注意点:
1. 需要给这个组件的根标签设置height: 100% ,因为这里用到的自动调整宽高插件是根据根标签的宽高改变
2. 左右联动中的性能优化,左侧每次触发滚动的时候要判断滚到新的一行时(新的索引)才改值,避免不必要的渲染