好客租房158-在城市界面使用navbar

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'
import NavHeader from '../../components/NavHeader'
// 数据格式化的方法
// 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组件有数据了
		// 调用 measureAllRows,提前计算 List 中每一行的高度,实现 scrollToRow 的精确跳转
		// 注意:调用这个方法的时候,需要保证 List 组件中已经有数据了!如果 List 组件中的数据为空,就会导致调用方法报错!
		// 解决:只要保证这个方法是在 获取到数据之后 调用的即可。
		this.cityListComponent.current.measureAllRows()
	}
	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>
				{/* <div className="name">上海</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">
				<NavHeader>城市选择</NavHeader>
				{/* 城市列表 */}
				<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

运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React-markdown是一个用于在React项目中渲染Markdown文件的组件。它可以将Markdown文件转换为HTML,并将其显示在网页上。通过使用React-markdown,您可以在React应用程序中实现在线浏览Markdown文件的功能。 Markdown-navbar是一个用于自动生成侧边导航栏目录的插件。它可以根据Markdown文件的标题层级结构生成导航栏,并且可以通过点击导航栏中的链接来快速跳转到相应的部分。 使用React-markdown和Markdown-navbar可以实现在React项目中浏览Markdown文件并自动生成侧边导航栏的功能。首先,您需要安装相关的依赖包,如yarn add react-markdown和yarn add markdown-navbar。然后,您可以使用React-markdown来渲染Markdown文件内容,并在合适的地方添加Markdown-navbar组件,这样就可以实现自动生成侧边导航栏目录的效果。 例如,在React项目中引入React-markdown和Markdown-navbar,并使用React-markdown来渲染Markdown文件的内容。您可以通过fetch函数获取Markdown文件的内容,并将其传递给ReactMarkdown组件进行渲染。同时,您还可以使用Markdown-navbar组件来生成侧边导航栏目录。通过这样的配置,您就可以实现在React项目中浏览Markdown文件并自动生成侧边导航栏的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [使用react-markdown与markdown-navbar实现在线浏览markdown文件并自动生成侧边导航栏目录(react项目)](https://blog.csdn.net/xz060585/article/details/129494847)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [markdown-navbar:React 的最佳降价导航栏](https://download.csdn.net/download/weixin_42102713/20451909)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值