React项目实战之租房app项目(六)渲染房源列表axios优化封装顶部搜索栏列表找房模块之条件筛选

news2024/11/27 4:21:51

前言

目录

  • 前言
  • 一、地图找房模块-获取并渲染房源列表
    • 1.1 房源列表示例图
    • 1.2 实现步骤
    • 1.3 代码示例
  • 二、axios优化
    • 2.1 问题概述
    • 2.2 配置生产环境和开发环境
    • 2.3 axios优化
  • 三、封装顶部搜索导航栏
  • 四、列表找房模块-导入顶部导航栏组件
  • 五、列表找房模块-条件筛选(上)
    • 5.1 条件筛选效果图
    • 5.2 功能分析
    • 5.3 标题菜单组件FilterTitle组件实现
  • 总结

一、地图找房模块-获取并渲染房源列表

1.1 房源列表示例图

在这里插入图片描述

1.2 实现步骤

1、在单击事件中,获取小区下的所有房源数据
2、展示房源列表
3、渲染获取到的房源列表
4、调用地图 panBy() 方法,移动地图到中间位置。
5、监听地图 movestart 事件,在地图移动时隐藏房源列表。

1.3 代码示例

在src/pages/Map/index.js中添加如下代码:

  // 创建小区覆盖物
  createRect(point, name, count, id) {
    // 创建覆盖物
    const label = new BMap.Label('', {
      position: point,
      offset: new BMap.Size(-50, -28)
    })

    // 给 label 对象添加一个唯一标识
    label.id = id

    // 设置房源覆盖物内容
    label.setContent(`
      <div class="${styles.rect}">
        <span class="${styles.housename}">${name}</span>
        <span class="${styles.housenum}">${count}套</span>
        <i class="${styles.arrow}"></i>
      </div>
    `)

    // 设置样式
    label.setStyle(labelStyle)

    // 添加单击事件
    label.addEventListener('click', e => {
      //调用获取房源列表方法
      this.getHousesList(id)

      // 获取当前被点击项
      const target = e.changedTouches[0]
      // 调用地图 panBy() 方法,移动地图到中间位置 
      this.map.panBy(
        window.innerWidth / 2 - target.clientX,
        (window.innerHeight - 330) / 2 - target.clientY
      )
    })

    // 添加覆盖物到地图中
    this.map.addOverlay(label)
  } 

获取小区房源数据方法:

  // 获取小区房源数据
  async getHousesList(id) {
    const res = await axios.get(`http://localhost:8080/houses?cityId=${id}`)
    this.setState({
      housesList: res.data.body.list,

      // 展示房源列表
      isShowList: true
    })
  }

渲染小区房源列表方法:

  // 封装渲染房屋列表的方法
  renderHousesList() {
    return this.state.housesList.map(item => (
      <div className={styles.house} key={item.houseCode}>
        <div className={styles.imgWrap}>
          <img
            className={styles.img}
            src={`http://localhost:8080${item.houseImg}`}
            alt=""
          />
        </div>
        <div className={styles.content}>
          <h3 className={styles.title}>{item.title}</h3>
          <div className={styles.desc}>{item.desc}</div>
          <div>
            {/* ['近地铁', '随时看房'] */}
            {item.tags.map((tag, index) => {
              const tagClass = 'tag' + (index + 1)
              return (
                <span
                  className={[styles.tag, styles[tagClass]].join(' ')}
                  key={tag}
                >
                  {tag}
                </span>
              )
            })}
          </div>
          <div className={styles.price}>
            <span className={styles.priceNum}>{item.price}</span>/</div>
        </div>
      </div>
    ))
  }

在render方法中渲染房源列表,通过isShowList控制显示与隐藏:

render() {
    return (
      <div className={styles.map}>
        {/* 顶部导航栏组件 */}
        <NavHeader>地图找房</NavHeader>
        {/* 地图容器元素 */}
        <div id="container" className={styles.container} />

        {/* 房源列表 */}
        {/* 添加 styles.show 展示房屋列表 */}
        <div
          className={[
            styles.houseList,
            this.state.isShowList ? styles.show : ''
          ].join(' ')}
        >
          <div className={styles.titleWrap}>
            <h1 className={styles.listTitle}>房屋列表</h1>
            <Link className={styles.titleMore} to="/home/list">
              更多房源
            </Link>
          </div>

          <div className={styles.houseItems}>
            {/* 房屋结构 */}
            {this.renderHousesList()}
          </div>
        </div>
      </div>
    )
  }

注意:房源列表相关样式在index.module.css中,这里不做过多展示

最后,在初始化地图方法中绑定地图移动事件隐藏房源列表:

// 给地图绑定移动事件
map.addEventListener('movestart', () => {
  if (this.state.isShowList) {
    this.setState({
      //隐藏房源列表
      isShowList: false
    })
  }
})

二、axios优化

2.1 问题概述

当每一次请求接口的时候,都需要写相同的baseUrl。例如:http://localhost:8080
这样太繁琐,而且当我们的项目部署上线时,很难替换

2.2 配置生产环境和开发环境

配置步骤:

1、在项目根目录中创建文件 .env.development
2、在该文件中添加环境变量
//环境变量约定REACT_APP开头
REACT_APP_URL =http://localhost:8080
3、重新启动脚手架,脚手架在运行的时候就会解析这个文件
4、在utils/url.js 中,创建BASE_URL 变量
5、导出BASE_URL

代码示例:
在src/utils/url.js中添加如下代码:

// 配置baseURL
export const BASE_URL = process.env.REACT_APP_URL

最后,可以在其他组件导入使用:

import {BASE_URL} from '../../utils/url.js'

2.3 axios优化

实现步骤:

1、在utils/api.js 中,导入 axios和BASE_URL
2、调用 axios.create() 方法创建一个axios实例
3、给 create 方法,添加配置baseURL,值为 BASE_URL
4、导出API对象

代码示例:
在src/utils/api.js中添加如下代码:

import axios from 'axios'
import { BASE_URL } from './url.js'

// 创建axios的配置文件,里面配置baseURL路径
const config = {
    baseURL: BASE_URL
}

// 根据create 方法来构建axios对象
const instance = axios.create(config)

export { instance }

三、封装顶部搜索导航栏

实现步骤:

1、在components 目录中创建组件 SearchHeader/index.js
2、把之前写过的结构拷贝到这个文件中
3、然后把跟首页相关的数据去掉,标题,城市名称
4、通过props来进行传递

代码示例:
在src/components/SearchHeader/index.js中添加如下代码:

import { Flex } from 'antd-mobile';
import React from 'react'
import {withRouter} from 'react-router-dom'
import './index.scss'
import PropTypes from 'prop-types'

function SearchHeader({ history, cityName, className}) {
    return (
        <Flex className={['search-box', className || ''].join(' ')}>
            {/* 左侧白色区域 */}
            <Flex className="search">
                {/* 位置 */}
                <div className="location" onClick={() => history.push('/citylist')}>
                    <span className="name">{cityName}</span>
                    <i className="iconfont icon-arrow" />
                </div>

                {/* 搜索表单 */}
                <div className="form" onClick={() => history.push('/search')}>
                    <i className="iconfont icon-seach" />
                    <span className="text">请输入小区或地址</span>
                </div>
            </Flex>
            {/* 右侧地图图标 */}
            <i className="iconfont icon-map" onClick={() => history.push('/map')} />
        </Flex>
    )
}
// 设置校验
SearchHeader.propTypes = {
    cityName: PropTypes.string.isRequired
}
export default withRouter(SearchHeader)

四、列表找房模块-导入顶部导航栏组件

实现步骤:

1、在找房页面 SearchHeader 组件基础上,调整结构(添加返回icon等)。
2、给 SearchHeader 组件传递 className 属性,来调整组件样式,让其适应找房页面效果。

代码示例:
然后在src/pages/Houselist/index.js中导入顶部搜索栏组件:

import React from 'react'
import { Flex } from 'antd-mobile'

// 导入搜索导航栏组件
import SearchHeader from '../../components/SearchHeader'

// 导入样式
import styles from './index.module.css'

// 获取当前定位城市信息
const { label } = JSON.parse(localStorage.getItem('hkzf_city'))

export default class HouseList extends React.Component {
  render() {
    return (
      <div>
        <Flex className={styles.header}>
          <i
            className="iconfont icon-back"
            onClick={() => this.props.history.go(-1)}
          />
          <SearchHeader cityName={label} className={styles.searchHeader} />
        </Flex>
      </div>
    )
  }
}

最后,在当前目录下创建index.module.css,设置相应的样式

五、列表找房模块-条件筛选(上)

5.1 条件筛选效果图

在这里插入图片描述

5.2 功能分析

条件筛选需要具备的功能如下:

1、点击标题菜单,展开条件筛选对话框,被点击的标题高亮
2、点击取消按钮或空白区域,隐藏对话框,取消标题高亮
3、选择筛选条件后,点击确定按钮,隐藏对话框,当前标题高亮
4、打开对话框时,如果有选择的条件,那么默认显示已选择的条件
5、打开对话框已经隐藏对话框有动画效果
6、标题框具有吸顶功能

要实现以上功能需要封装4个组件分工合作,分别是:

1、父组件:Filter
2、子组件:FilterTitle 标题菜单组件
3、子组件:FilterPicker 前三个菜单对应的内容组件
4、子组件:FilterMore 最后一个菜单对应的内容组件

5.3 标题菜单组件FilterTitle组件实现

实现思路:

1、根据标题菜单数据,渲染标题列表
2、标题可以被点击
3、标题点击时高亮,有筛选条件选中时高亮
4、由父组件Filter提供高亮状态,子组件通过props接受状态来实现高亮
5、原则是单一数据源,只由父组件Filter提供和修改状态,其他组件只负责接收状态

实现步骤:

1、在src/pages/Houselist目录下,新建components文件夹
2、在components目录下新建Filter,FilterTitle,FilterPicker,FilterMore组件
3、在FilterTitle组件中通过props接收高亮状态对象 titleSelectedStatus
4、遍历titleList数组,渲染标题列表
5、判断高亮对象中当前标题是否高亮,如果是,添加高亮类
6、给标题项绑定单击事件,在事件中调用父组件传过来的方法 onClick
7、将当前标题type,通过onClick的参数,传递给父组件
8、父组件中接收到当前type,修改标题的选中状态为true

代码示例:
首先,在src/pages/HouseList/components/Filter/index.js中添加如下代码:

// 标题高亮状态
// true 表示高亮; false 表示不高亮
const titleSelectedStatus = {
  area: false,
  mode: false,
  price: false,
  more: false
}

export default class Filter extends Component {
  state = {
    titleSelectedStatus
  }

  // 点击标题菜单实现高亮
  // 父组件中接收到当前type,修改标题的选中状态为true
  onTitleClick = type => {
    this.setState(prevState => {
      return {
        titleSelectedStatus: {
          // 获取当前对象中所有属性的值
          ...prevState.titleSelectedStatus,
          [type]: true
        }
      }
    })
  }

  render() {
    const { titleSelectedStatus } = this.state

    return (
      <div className={styles.root}>
        <div className={styles.content}>
          {/* 标题栏 */}
          <FilterTitle
            titleSelectedStatus={titleSelectedStatus}
            onClick={this.onTitleClick}
          />
        </div>
      </div>
    )
  }
}

然后,在src/pages/HouseList/components/FilterTitle/index.js中添加如下代码:

// 条件筛选栏标题数组:
const titleList = [
  { title: '区域', type: 'area' },
  { title: '方式', type: 'mode' },
  { title: '租金', type: 'price' },
  { title: '筛选', type: 'more' }
]

export default function FilterTitle({ titleSelectedStatus, onClick }) {
  return (
    <Flex align="center" className={styles.root}>
      {titleList.map(item => {
        const isSelected = titleSelectedStatus[item.type]
        return (
          <Flex.Item key={item.type} onClick={() => onClick(item.type)}>
            {/* 选中类名: selected */}
            <span
              className={[
                styles.dropdown,
                // 判断当前的标题是否是选中状态,如果是,设置选中的样式
                isSelected ? styles.selected : ''
              ].join(' ')}
            >
              <span>{item.title}</span>
              <i className="iconfont icon-arrow" />
            </span>
          </Flex.Item>
        )
      })}
    </Flex>
  )
}

总结

由于篇幅有限,条件筛选其他组件将留到下一篇笔记介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python将Excel文件插入Mysql数据库(脚本)

目录前言最近接到一个需求&#xff0c;就是将多个Eccel文件&#xff08;表头相同&#xff1b;每个都非常大&#xff0c;约60多万行&#xff0c;每个都是&#xff01;&#xff01;&#xff09;先合并在一起&#xff0c;再做一些处理&#xff0c;但是Excel表格一个文件根本存不下…

Python矩阵乘法 二重循环实现 + 列表推式

这是python 矩阵乘法的简单例子 col 2 row 2 a [[1, 2], [3, 4]] b [[5, 6], [7, 8]] c [[0, 0], [0, 0]] “”" a b c 二维矩阵初始化 c [[0 for col in range(col)] for row in range(row)] a [[0 for col in range(col)] for row in range(row)] b [[0 for c…

Android热修复,精简学习

接入热修复 接入热修复流程如下&#xff1a; 配置开发环境在控制台创建应用在客户端创建新工程签名配置加密信息编写代码发布带有热修复功能的客户端版本 配置开发环境 在控制台创建应用 在控制台创建 mPaaS 应用。此时&#xff0c;本地还没有带签名的 APK&#xff0c;因此…

面试:插件化相关---broadcastReceiver

实现原理 1 采用的模型 Android中的广播使用了设计模式中的观察者模式&#xff1a;基于消息的发布 / 订阅事件模型因此&#xff0c;Android将广播的发送者 和 接收者 解耦&#xff0c;使得系统方便集成&#xff0c;更易扩展 2 模型讲解 模型中有3个角色&#xff1a; 消息订阅…

小程序项目结构

pages 用来存放所有小程序的页面utils 用来存放工具性质的模块(例如:格式化时间的自定义模块)app.js 小程序项目的入口文件app.json 小程序项目的全局配置文件app.wxss 小程序项目的全局样式文件project.config.json 项目的配置文件sitemap.json 用来配置小程序及其页面是否允许…

【数据结构-查找】散列表

文章目录1 线性探测法1.1 查找成功时的 ASL1.2 查找失败时的 ASL1.3 散列表的装填因子 α2 拉链法1 线性探测法 1.1 查找成功时的 ASL 查找元素 47&#xff08;散列函数&#xff1a;3&#xff09;次数&#xff1a;1查找元素 7&#xff08;散列函数&#xff1a;11&#xff09;次…

云上办公便捷、安全,就用华为云桌面

云上办公便捷、安全&#xff0c;就用华为云桌面&#xff01; 根据IDC提出的“未来工作空间”的概念&#xff0c;未来工作空间意味着将打破时空与地域的限制&#xff0c;让员工随时随地工作。未来工作空间也将成为企业整体数字化转型战略中的必要组成部分。 恰逢其时&#xff0…

kubernetes Pod详解

文章目录Pod生命周期创建和终止pod的创建过程pod的终止过程初始化容器钩子函数容器探测重启策略Pod调度定向调度NodeNameNodeSelector亲和性调度NodeAffinityPodAffinityPodAntiAffinity污点和容忍污点&#xff08;Taints&#xff09;容忍&#xff08;Toleration&#xff09;Po…

【测试沉思录】19. 如何设置 JMeter 线程组?

作者&#xff1a;宋赟 编辑&#xff1a;毕小烦 最近有不少测试同学问我 JMeter 线程组如何设置并发的问题&#xff0c;发现很多人对线程组里的参数不是很清楚&#xff0c;今天就科普一下 JMeter 线程组的信息&#xff0c;也简单介绍一下不同场景的并发策略。 1. 线程组是什么 …

制作一个简单HTML游戏网页(HTML+CSS)米哈游 1页 带轮播图

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游戏官网 | 游戏网站 | 电竞游戏 | 游戏介绍 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 …

K3S +Helm+NFS最小化测试安装部署只需十分钟

作者&#xff1a;郝建伟 k3s 简介 官方文档&#xff1a;k3s 什么是k3s k3s 是一个轻量级的 Kubernetes 发行版 它针对边缘计算、物联网等场景进行了高度优化。 k3s 有以下增强功能&#xff1a;打包为单个二进制文件。 使用基于 sqlite3 的轻量级存储后端作为默认存储机制。…

【附源码】计算机毕业设计JAVA专利查询与发布系统设计与实现

【附源码】计算机毕业设计JAVA专利查询与发布系统设计与实现 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1…

BI数据分析

一 前言 数据分析一般需要掌握Excel、SQL&#xff0c;再强大的需要掌握python等。目前市面上的数据BI工具&#xff0c;就是用来优化复杂的数据分析过程&#xff0c;解放相关人员的生产力的&#xff0c;不再为了一个需求而漫长等待和重复多次沟通&#xff0c;从而让人员可以更多…

Echarts柱状图label优化历程

问题1 由于项目数据记录多或者数据值大的时候&#xff0c;会出现label重叠的现象&#xff0c;如下图。 解决方案 针对上述问题&#xff0c;解决思路如下&#xff1a; 1、求Y轴的最大值&#xff08;我们用Y轴的最大值&#xff0c;去计算每个柱子在整个图中的占比&#xff09;…

分布式文件系统

0.0 分布式文件系统 一般做法&#xff1a; 传统的模式是我们通过tomcat或者nginx&#xff0c;存放静态资源文件。 存在的问题&#xff1a; 单个节点会出现存不下的情况&#xff0c;需要多个节点。 分布式文件系统 需要一个系统来管理多个计算机节点上的文件数据&#xff…

[附源码]计算机毕业设计JAVA小锅米线点餐管理系统

[附源码]计算机毕业设计JAVA小锅米线点餐管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

Python Faker库造伪数据

pip install Faker -i https://pypi.tuna.tsinghua.edu.cn/simple 在生成数据时&#xff0c;先调用unique&#xff0c;上面例子中的代码则改成下面这样 from faker import Faker def faker_demo(n): f Faker(“zh-CN”) l [] for i in range(n): # 代码更改处&#xff0c;…

安全高效应对混合办公新趋势 腾讯四大协同办公产品亮相

11月30日下午&#xff0c;2022腾讯全球数字生态大会「安全高效协同办公」专场在线上召开。论坛针对混合办公变革下的安全风险进行解析&#xff0c;并给出便捷规范的评估工具协助各行业客户评估自身办公安全成熟度&#xff0c;详细解读了腾讯数据安全解决方案、腾讯零信任iOA、腾…

Docker快速入门【极速浏览版】

文章目录11.1 Docker为什么出现1.2 Docker理念1.3 容器和虚拟机比较⭐️1.4 容器为什么比虚拟机快&#xff1f;⭐️1.5 Docker的基本组成⭐️1.6 Docker一个基本流程⭐️1.7 Docker架构⭐️1.7.1 入门版1.7.2 架构板22.1 Centos Docker安装2.2 前提条件2.3 官网安装doc2.4 查看…

安科瑞集中监控,剩余电流监测,温度保护电气火灾监控探测器

安科瑞 王晶淼/司红霞 一、电气火灾和爆炸的原因 电气火灾和爆炸在火灾、爆炸事故中占有很大的比例。如线路、电动机、开关等电气设备都可能引起火灾。变压器等带油电气设备除了可能发生火灾,还有爆炸的危险。造成电气火灾与爆炸的原因很多。除设备缺陷、安装不当等设计和施工…