一、功能
- 从首页列表点进去,转到详情页
- 列表、详情从Api获取
- Api列表:http://a.itying.com/api/productlist
详情:http://a.itying.com/api/productcontent?id=5ac1a22011f48140d0002955
二、知识点
- 路由需要安装,并引用后才能用
- 路由的使用
- api解析:axios ;安装并引用后才能用
- 生命周期函数
三、实战
src目录结构:
【Src】
│ App.css
│ App.js
│ ...
├─components
│ Home.js
│ Pcontent.js
│ 模板.js
├─css
│ basic.css
│ index.css
│ pcontent.css
└─images
1.jpg
2.jpg
3.jpg
App.js
import React from 'react';
//import './App.css';
import { BrowserRouter as Router, Route } from 'react-router-dom'; //引入路由模块
import Home from './components/Home';
import Pcontent from './components/Pcontent';
function App() {
return (
<Router>
<div>
<Route exact path="/" component={Home} />
<Route path="/Pcontent/:_id" component={Pcontent} />
</div>
</Router>
);
}
export default App;
Home.js
import React,{Component} from 'react';
import {Link} from 'react-router-dom';
import '../css/index.css';
import axios from 'axios'; //或写成:const axios = require('axios');
//import { thisExpression } from '@babel/types';
class Home extends Component{
constructor(props){
super(props);
this.state={
list:[],
domain:'http://a.itying.com/'
}
}
//获取Api接口的数据
getDataApi=()=>{
//拼装得到完整的Api接口链接
var api=this.state.domain+"api/productlist";
axios.get(api)
.then((response)=>{
console.log(response);
this.setState({
list:response.data.result
})
})
.catch(function(error){
console.log(error);
})
}
//生周函数:页面渲染完成后加载
componentDidMount(){
//调用函数得到api接口数据
this.getDataApi();
}
render(){
return(
<div>
<header className="index_header">
<div className="hlist">
<img alt='热销榜' src={require('../images/rexiao.png')} />
<p>热销榜</p>
</div>
<div className="hlist">
<img alt='点过的菜' src={require('../images/caidan.png')} />
<p>点过的菜</p>
</div>
<div className="hlist">
<img alt='猜你喜欢' src={require('../images/sousuo.png')} />
<p>猜你喜欢</p>
</div>
</header>
<div className="content">
{
this.state.list.map((value,key)=>{
return(
<div className="item" key={key}>
<h3 className="item_cate">{value.title}</h3>
<ul className="item_list">
{
value.list.map((v,k)=>{
return(
<li key={k}>
<div className="inner">
<Link to={`/Pcontent/${v._id}`}>
<img alt={v.title} src={`${this.state.domain}${v.img_url}`} />
</Link>
<p className="title">{v.title}</p>
<p className="price">{v.price}元</p>
</div>
</li>
)
})
}
</ul>
</div>
)
})
}
</div>
</div>
)
}
}
export default Home;
react解析html
https://reactjs.org/docs/dom-elements.html
<div className="p_content" dangerouslySetInnerHTML={{__html: this.state.list.content}}> </div>
【Pcontent.js】
import React, { Component } from 'react';
import axios from 'axios';
import '../css/pcontent.css';
import '../css/basic.css';
import {Link} from 'react-router-dom';
class Pcontent extends Component {
constructor(props){
super(props);
this.state={
detail_list:[],
domain:'http://a.itying.com/'
}
}
componentWillMount(){
//获取整个props查看数据结构
console.log(this.props)
//根据数据结构找到传过来的_id
console.log(this.props.match.params._id)
//根据传过来的_id获取对应详情页面
var id=this.props.match.params._id;
var api='http://a.itying.com/api/productcontent?id='+ id;
axios.get(api)
.then((response)=>{
console.log(response);
this.setState({
detail_list:response.data.result[0]
})
})
.catch((error)=>{
console.log(error)
})
}
render() {
return (
<div className='pcontent'>
<div className="back"><Link to='/'>返回</Link></div>
<div className="p_content">
<div className="p_info">
<img alt={this.state.detail_list.title} src={`${this.state.domain}${this.state.detail_list.img_url}`}/>
<h2>{this.state.detail_list.title}</h2>
<p className="price">{this.state.detail_list.price}元</p>
</div>
<div className="p_detial">
<h3>
商品详情
</h3>
{/*html解析写法*/}
<div className="p_content" dangerouslySetInnerHTML={{__html: this.state.detail_list.content}}>
</div>
</div>
</div>
<footer className="pfooter">
<div className="cart">
<strong>数量:</strong>
<div className="cart_num">
<div className="input_left">-</div>
<div className="input_center">
<input type="text" readOnly="readonly" value="1" name="num" id="num" />
</div>
<div className="input_right">+</div>
</div>
</div>
<button className="addcart">加入购物车</button>
</footer>
</div>
);
}
}
export default Pcontent;
basic.css
@charset "UTF-8";
body, div, ul, li, ol, h1, h2, h3, h4, h5, h6, input, textarea, select, p, dl, dt, dd, a, img, button, form, table, th, tr, td, tbody, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
margin: 0;
padding: 0; }
html {
font-size: 62.5%;
/* 根元素是10px; 16*62.5%=10 默认在pc端根元素会解析成12px */ }
body {
font: 12px/1.5 'Microsoft YaHei','宋体', Tahoma, Arial, sans-serif;
color: #555;
background-color: #F7F7F7; }
em, i {
font-style: normal; }
ul, li {
list-style-type: none; }
strong {
font-weight: normal; }
.clearfix:after {
content: "";
display: block;
visibility: hidden;
height: 0;
clear: both; }
/*# sourceMappingURL=basic.css.map */
index.css
@charset "UTF-8";
.index_header {
96%;
margin: 0 auto;
height: 4.4rem;
background: #fff;
margin-top: 1rem;
display: flex;
border-radius: .5rem; }
.index_header .hlist {
flex: 1;
text-align: center;
padding-top: .2rem;
border-right: 1px solid #eee; }
.index_header .hlist img {
2rem;
height: 2rem;
margin: 0 auto; }
.index_header .hlist:last-child {
border-right: none; }
/*列表*/
.item .item_cate {
text-align: center;
padding: .5rem; }
.item .item_list {
display: flex;
flex-wrap: wrap;
padding: 0px .5rem; }
.item .item_list li {
33.3%;
padding: .5rem;
box-sizing: border-box; }
.item .item_list li .inner {
background: #fff;
100%;
border-radius: .5rem;
overflow: hidden; }
.item .item_list li .inner img {
100%; }
.item .item_list li .inner p {
padding: .2rem .5rem; }
.item .item_list li .inner .title {
font-weight: bold; }
/*侧边栏*/
.left_cate {
/*css3运动 加过渡效果*/
transition: all 1s;
transform: translate(-100%, 0);
z-index: 2;
6rem;
height: 100%;
position: fixed;
background: #eee;
top: 0px;
left: 0px; }
.left_cate ul {
position: absolute;
height: 100%;
padding: .5rem;
z-index: 3;
background: #eee; }
.left_cate ul li {
line-height: 4.4rem; }
.left_cate .nav_cate {
position: absolute;
right: -3.5rem;
background: rgba(132, 128, 128, 0.9);
top: 42%;
5rem;
height: 4rem;
text-align: center;
border-radius: 0rem 50% 50% 0rem;
z-index: 2; }
.left_cate .nav_cate img {
1.8rem;
height: 1.8rem;
margin-left: 1rem;
margin-top: .4rem; }
.left_cate .nav_cate p {
color: #fff;
margin-left: 1rem;
margin-top: -0.3rem; }
/*透明层*/
.bg {
position: fixed;
100%;
height: 100%;
background: rgba(132, 128, 128, 0.4);
left: 0px;
top: 0px;
z-index: 1;
display: none; }
/*首页导航*/
.footer_nav {
height: 4.4rem;
4.4rem;
background: #000;
position: fixed;
color: #fff;
bottom: .5rem;
left: .5rem;
text-align: center;
border-radius: 50%; }
.footer_nav img {
1.8rem;
height: 1.8rem;
margin-top: .4rem; }
.footer_nav p {
position: relative;
top: -0.2rem; }
/*导航弹出层*/
.footer_nav_show {
100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, 0.6);
z-index: 2; }
.footer_nav_show .list li {
height: 4.4rem;
4.4rem;
background: #000;
position: absolute;
color: #fff;
left: .5rem;
text-align: center;
border-radius: 50%; }
.footer_nav_show .list li img {
1.8rem;
height: 1.8rem;
margin-top: .4rem; }
.footer_nav_show .list li p {
position: relative;
top: -0.2rem;
font-size: 1rem; }
.footer_nav_show .list li:nth-child(1) {
bottom: 15.4rem;
left: 0px; }
.footer_nav_show .list li:nth-child(2) {
bottom: 12.4rem;
left: 30%;
margin-left: -2.2rem; }
.footer_nav_show .list li:nth-child(3) {
bottom: 7.4rem;
left: 45%;
margin-left: -2.2rem; }
.footer_nav_show .list li:nth-child(4) {
left: 50%;
margin-left: -2.2rem;
bottom: .5rem; }
.footer_nav_show .list li:nth-child(5) {
left: .5rem;
bottom: .5rem; }
.footer_cart {
height: 4.4rem;
4.4rem;
background: red;
position: fixed;
color: #fff;
bottom: .5rem;
right: .5rem;
text-align: center;
border-radius: 50%; }
.footer_cart img {
1.8rem;
height: 1.8rem;
margin-top: .4rem; }
.footer_cart p {
position: relative;
top: -0.2rem; }
/*# sourceMappingURL=index.css.map */
pcontent.css
@charset "UTF-8";
.back {
height: 3.8rem;
line-height: 3.8rem;
3.8rem;
border-radius: 50%;
background: #000;
position: fixed;
top: .5rem;
left: .5rem;
color: #fff; }
.back:before {
content: "";
display: block;
.8rem;
height: .8rem;
border-left: .2rem solid #fff;
border-bottom: .2rem solid #fff;
float: left;
position: relative;
top: 1.3rem;
left: .6rem;
transform: rotate(45deg);
margin-right: .4rem; }
.p_content .p_info {
background: #fff; }
.p_content .p_info img {
100%;
height: 18rem; }
.p_content .p_info h2 {
padding: .2rem .5rem; }
.p_content .p_info .price {
padding: .2rem .5rem;
color: red; }
.p_content .p_detial {
background: #fff;
margin-top: 1rem; }
.p_content .p_detial h3 {
padding: .5rem; }
.p_content .p_detial .p_content {
padding: 1rem; }
.p_content .p_detial .p_content img {
max- 100%;
display: block;
margin: 0 auto; }
.p_content .p_detial .p_content * {
line-height: 1.5;
color: #666; }
/*搴曢儴*/
.pfooter {
position: fixed;
bottom: 0px;
height: 4.4rem;
line-height: 4.4rem;
background: #fff;
left: 0px;
100%;
border-top: 1px solid #eee; }
.pfooter .cart {
float: left;
display: flex; }
.pfooter .cart strong {
flex: 1;
font-size: 1.6rem;
padding: 0rem .5rem; }
.pfooter .cart .cart_num {
10rem;
display: flex;
margin-top: .8rem; }
.pfooter .cart .cart_num .input_left, .pfooter .cart .cart_num .input_right {
flex: 1;
2.8rem;
height: 2.8rem;
line-height: 2.8rem;
text-align: center;
color: red;
border: 1px solid #eee;
font-size: 2.4rem; }
.pfooter .cart .cart_num .input_center {
flex: 1; }
.pfooter .cart .cart_num .input_center input {
2rem;
text-align: center;
100%;
height: 2.8rem;
border: none;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
float: left; }
.pfooter .addcart {
float: right;
background: red;
color: #fff;
height: 3rem;
border: none;
padding: 0 .5rem;
border-radius: .5rem;
margin-top: .8rem;
margin-right: .5rem; }
/*# sourceMappingURL=pcontent.css.map */