主页(九)-模块——轮播图-菜单分类-租房小组-最新资讯-顶部导航栏
实例
第一步:界面文件
src/views/index/Index.js
/*
主页
*/
import React from 'react'
import { Carousel, Flex, WhiteSpace, Grid, NavBar, Icon } from 'antd-mobile'
import axios from 'axios'
import './Index.scss'
// 菜单的路径
import nav1 from '../../assets/images/nav-1.png'
import nav2 from '../../assets/images/nav-2.png'
import nav3 from '../../assets/images/nav-3.png'
import nav4 from '../../assets/images/nav-4.png'
class Index extends React.Component {
constructor (props) {
super(props)
this.state = {
swiper: [],
groups: [],
news: [],
imgHeight: 212
}
}
loadSwiper = async () => {
// axios.get('home/swiper')
// .then(res => {
// this.setState({
// swiper: res.data.body
// })
// })
let data = await axios.get('home/swiper')
this.setState({
swiper: data.body
})
}
loadGroud = async () => {
// 租房小组数据加载
let data = await axios.get('home/groups')
this.setState({
groups: data.body
})
}
loadNews = async () => {
// 最新资讯数据加载
let data = await axios.get('home/news')
this.setState({
news: data.body
})
}
componentDidMount () {
// 加载轮播图数据
this.loadSwiper()
this.loadGroud()
this.loadNews()
}
renderSwiper = () => {
// 动态生成轮播图的列表
return this.state.swiper.map(item => {
return (
<a
key={item.id}
href="http://itcast.cn"
style={{ display: 'inline-block', width: '100%', height: this.state.imgHeight }}>
<img
src={`http://localhost:8080${item.imgSrc}`}
alt=""
style={{ width: '100%', verticalAlign: 'top' }}
onLoad={() => {
// 图片加载完成时触发
// fire window resize event to change height
window.dispatchEvent(new Event('resize'));
// 处理a标签的高度
this.setState({ imgHeight: 'auto' });
}}
/>
</a>
)
})
}
renderMenu = () => {
// 动态生成菜单
let menuData = [{
id: 1,
mname: '整租',
imgSrc: nav1
}, {
id: 2,
mname: '合租',
imgSrc: nav2
}, {
id: 3,
mname: '地图找房',
imgSrc: nav3
}, {
id: 4,
mname: '去出租',
imgSrc: nav4
}]
return menuData.map(item => (
<Flex.Item key={item.id}>
<img src={item.imgSrc} alt=""/>
<p>{item.mname}</p>
</Flex.Item>
))
}
renderGridItem = (item) => {
// 生成宫格效果
return (
<Flex className="grid-item" justify="between">
<div className="desc">
<h3>{item.title}</h3>
<p>{item.desc}</p>
</div>
<img src={`http://localhost:8080${item.imgSrc}`} alt="" />
</Flex>
)
}
renderNews = () => {
// 生成最新资讯列表
return this.state.news.map(item => (
<div className="news-item" key={item.id}>
<div className="imgwrap">
<img
className="img"
src={`http://localhost:8080${item.imgSrc}`}
alt=""
/>
</div>
<Flex className="content" direction="column" justify="between">
<h3 className="title">{item.title}</h3>
<Flex className="info" justify="between">
<span>{item.from}</span>
<span>{item.date}</span>
</Flex>
</Flex>
</div>
))
}
render () {
return (
<div>
{/*顶部导航*/}
<NavBar
mode="dark"
icon={<Icon type='left'/>}
rightContent={[
<Icon
key="0"
type="search"
style={{ marginRight: '16px' }}
/>
]}
>
上海
</NavBar>
{/*轮播图效果*/}
<Carousel
autoplay={false}
infinite>
{this.renderSwiper()}
</Carousel>
{/*菜单*/}
{/* 上下留白组件实现 */}
<WhiteSpace size="lg" />
<Flex className='home-menu'>
{this.renderMenu()}
</Flex>
{/*租房小组*/}
<div className="group">
<Flex className="group-title" justify="between">
<h3>租房小组</h3>
<span>更多</span>
</Flex>
<Grid
data={this.state.groups}
columnNum={2}
square={false}
renderItem={this.renderGridItem}
/>
</div>
{/*最新资讯*/}
<div className="news">
<h3 className="group-title">最新资讯</h3>
{this.renderNews()}
</div>
</div>
)
}
}
export default Index
第二步:界面文件样式
// 样式写法——scss:嵌套关系
.home-menu {
.am-flexbox-item {
text-align: center;
img {
height: 48px;
}
p {
margin-top: 7px;
font-size: 13px;
}
}
}
.group {
overflow: hidden;
padding: 0 10px;
background-color: #f6f5f6;
// &-代表父级选择器,一动全动
&-title {
margin: 15px 0 15px 0;
h3 {
font-size: 15px;
}
span {
font-size: 14px;
color: #787d82;
}
}
// 宫格
.am-flexbox {
margin-bottom: 10px;
background-color: transparent;
.am-grid-item {
margin-right: 0;
background-color: #fff;
&:first-child {
margin-left: 10px;
}
}
}
.grid-item {
padding: 0 13px;
.desc {
h3 {
margin-bottom: 5px;
font-size: 13px;
}
p {
color: #999;
font-size: 12px;
}
}
img {
width: 55px;
}
}
}
.news {
padding: 10px;
background-color: #fff;
overflow: hidden;
.group-title {
margin: 10px 0 5px 10px;
font-size: 15px;
}
.news-item {
height: 120px;
padding: 15px 10px 15px 0;
border-bottom: 1px solid #e5e5e5;
}
.news-item:last-child {
border: 0;
}
.imgwrap {
float: left;
height: 90px;
width: 120px;
}
.img {
height: 90px;
width: 120px;
}
.content {
overflow: hidden;
height: 100%;
padding-left: 12px;
}
.title {
margin-bottom: 15px;
font-size: 14px;
}
.info {
width: 100%;
color: #9c9fa1;
font-size: 12px;
}
.message-title {
margin-bottom: 48px;
}
}
第三步:基准路径和拦截器配置
App.js
import React from 'react';
import './App.css';
// import { Button } from 'antd-mobile'
import 'antd-mobile/dist/antd-mobile.css'
// 配置整体路由
import { BrowserRouter, Route, Redirect, Switch } from 'react-router-dom'
import Login from './views/login/Login.js'
import Home from './views/home/Home.js'
import axios from 'axios'
// 配置请求基准路径
axios.defaults.baseURL = 'http://localhost:8080/'
// 配置响应拦截器
axios.interceptors.response.use((res) => {
return res.data
})
function NotFound () {
return <div>没有该页面</div>
}
function App() {
return (
<BrowserRouter>
<Switch>
<Route path='/login' component={Login}/>
<Route path='/home' component={Home}/>
<Redirect exact from='/' to='/home'/>
<Route component={NotFound}/>
</Switch>
</BrowserRouter>
);
}
export default App;