使用React做个小demo
目标:
1)初始化项目
2)使用ant-mobile组件库
3)完成项目整体布局
4)完成首页轮播图
5)使用百度地图API完成定位功能
6)使用react-virtualized完成城市选择功能
项目准备
项目整体布局
首页模块
城市选择模块
react开发者工具(谷歌浏览器):https://www.cnblogs.com/gopark/p/12253892.html
一、项目准备
1)项目介绍
核心业务:在线找房(地图、条件搜索)、登录、房源发布
技术栈:
a)React核心库:react react-dom react-routerrouter-dom
b)脚手架:creat-react-app
c)数据请求:axois
d)UI组件库:antd-mobile
e)百度地图API
2)项目搭建
a)本地接口部署(数据库、接口)
b)使用脚手架初始化项目
本地接口部署
初始化项目
a)初始化项目:npx create-react-app projectName
b)启动项目:npm start
c)调整项目目录src的结构
3)配置基础路由
a)安装路由插件react-router-dom
npm i react-router-dom -S
b)导入路由组件:Router/Route/Link
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
c)在pages中创建Home/index.js CityList/index.js文件
d)使用Route组件配置首页和城市选择页面
<Route path="/home" component={Home} />
<Route path="/cityList" component={CityList} />
app.js文件内容如下
二、项目布局
页面有带TabBar和无TabBar两种样式
有TabBar的是靠路由嵌套实现
1、嵌套路由
路由内包含路由:Home组件表示父路由内容,News组件表示子路由内容
使用步骤
a)pages文件夹下创建News/index.jx组件
b)Home组件添加Route表示作为子路由出口
const Home = () => (
<div>
<Route path="/home/news" component={News} />
</div>
)
c)设置嵌套路的path,以父路由path开头(父组件展示,子组件才展示)
2、实现TabBar
1)基本使用
a)打开antd-mobile组件库中的组件TabBar文档
b)选择“APP型选项卡”菜单,点击“</>”显示源码
c)拷贝核心代码到Home组件中
d)调整代码,让项目跑起来
2)修改TabBar外观样式
a)修改TabBar菜单项文字标题
b)修改TabBar菜单项文字标题颜色(选中与未选中)
以上两步参考官网文档
c)使用字体图标,修改TabBar菜单的图标
在项目的assets中引进字体库文件
在index.js中引进字体图标库的样式文件
// 导入字体图标库的样式文件
import './assets/fonts/iconfont.css'
在TabBar.Item中使用字体图标,当在TabBar中设置了选中字体颜色,则选中图标的颜色同选中字体颜色一样
icon={<i className="iconfont icon-ind" />}
selectedIcon={<i className="iconfont icon-ind" />}
默认图标就修改了
d)修改TabBar菜单项图标大小
由于字体图标的大小是iconfont.css中控制的,需要重新给该其设置大小
新建Home/index.scss文件
.home{
.iconfont{
font-size: 20px;
}
}
在Home组件引进样式
// 导入组件自己的样式
import './index.scss';
提升Home/index.scss中的样式权重,即将类写在.home下面
<div className="home">
e)修改TabBar菜单位置,让其固定在页面底部
修改.am-tab-bar-bar的样式
.home{
.iconfont{
font-size: 20px;
}
.am-tab-bar-bar {
position: fixed;
bottom: 0;
}
}
3)实现TabBar
TabBar配合路由使用
a)根据TabBar组件文档,设置不渲染内容(保留菜单项,不显示内容),设置noRenderContent为true
<TabBar
tintColor="#21b97a"
barTintColor="white"
noRenderContent={true}
>
b)给TabBar.Item绑定点击事件,通过编程式导航实现路由切换功能
c)在点击事件中,调用props.history.push(),实现路由切换
<TabBar.Item
title="首页"
key="home"
icon={<i className="iconfont icon-ind" />}
selectedIcon={<i className="iconfont icon-ind" />}
selected={this.state.selectedTab === 'blueTab'}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
})
this.props.history.push('/home/list')
}}>
</TabBar.Item>
d)创建TabBar组件菜单项对应的其他3个组件,并在Home组件中配置路由信息
e)给菜单项添加selected属性,设置当前匹配的菜单项点亮,即通过location.pathname去匹配组件高亮
slectedTab = this.props.location.pathname
<TabBar.Item
selected = {selectedTab === '/home/list'}
/>
下面给出部分关键代码
constructor(props) {
super(props)
this.state = {
selectedTab: this.props.location.pathname
}
}
{/* 渲染子路由 */}
<Route path="/home/index" component={Index} />
<Route path="/home/list" component={List} />
<Route path="/home/news" component={News} />
<Route path="/home/profile" component={Profile} />
<TabBar.Item
title="首页"
key="home"
icon={<i className="iconfont icon-ind" />}
selectedIcon={<i className="iconfont icon-ind" />}
selected={this.state.selectedTab === '/home/index'}
onPress={() => {
this.setState({
selectedTab: '/home/index'
})
this.props.history.push('/home/index')
}}
data-seed="logId"
>
</TabBar.Item>
TabBar.Item代码重构
现在代码有4个TabBar.Item,而它们的结构一样,只是数据不一样,这样可以对数据封装,然后JSX就可以写一个,通过Array.map实现DOM编写
a)提供菜单数据(包含菜单项的特有信息)
const tabItems = [
{
title: '首页',
icon: 'icon-ind',
path: '/home/index'
}
]
b)使用map方法遍历数据,渲染TabBar.Item,即相同地方通过遍历实现去重
// 渲染TabBar.Item
renderTabBarItem() {
return tabItems.map((item) => {
return (
<TabBar.Item
icon={<i className={`iconfont ${item.icon}`}/>}
selectedIcon={<i className={`iconfont ${item.icon}`} />}
title={item.title}
key={item.title}
selected={this.state.selectedTab === item.path}
onPress={() => {
this.setState({
selectedTab: item.path
})
this.props.history.push(item.path)
}}
/>
)
})
}
三、首页模块
1、首页路由处理
路径不匹配的时候进行重定向到home页面;默认路由的时候重定向到home页面
a)修改首页Home/index.js中路由规则为:/home(去掉/index),精确匹配
<Route exact path="/home" component={Index}/>
b)配合默认路由path="/",利用render属性和<Redirect>组件,实现默认跳转到/home 路由文档,在根组件中书写
<Route exact path="/" render={() => <Redirect to="/home" />} />
c)render属性,是一个函数props,指定渲染内容
d)Redirect组件,实现路由重定向,to属性指定要跳转到的路由地址
App.js内容如下
import {BrowserRouter as Router, Route, Redirect} from 'react-router-dom'
// 导入组件
import Home from './pages/Home'
import CityList from './pages/CityList'
function App() {
return (
// Router包裹整个应用
<Router>
<div className="App">
{/* 配置默认路由 */}
<Route exact path="/" render={() => <Redirect to="/home" />} />
{/* 配置路由 */}
<Route path="/home" component={Home}/>
<Route path="/cityList" component={CityList}/>
</div>
</Router>
);
}
export default App;