需要进行判断,否则会进行多次数据请求
import React, {
useState, useEffect } from "react";
import axios from "axios";
import HotItem from "./hot_item";
import "./index.scss";
function MoviesHot() {
let [movies_hot, setMovies_hot] = useState([]);
useEffect(() => {
if (movies_hot.length !== 0) return;
axios
.get("/ajax/movieOnInfoList", {
params: {
token: ""
}
})
.then(ret => {
setMovies_hot((movies_hot = ret.data.movieList));
});
});
function renderHotItem() {
return movies_hot.map(item => <HotItem key={
item.id} {
...item}></HotItem>);
}
return <article id="hot_list">{
renderHotItem()}</article>;
}
export default MoviesHot;
然后进行简单的数据渲染
import React from "react";
import {
Button } from "antd-mobile";
function HotItem(props) {
function sc() {
return (
<p>
<span>观众评</span>
<span className="hot_sc">{
props.sc}</span>
</p>
);
}
function wish() {
return (
<p>
<span className="hot_wish">{
props.wish}</span>
<span>人想看</span>
</p>
);
}
return (
<article className="hot_item">
<section className="hot_img">
<img src={
props.img.replace("w.h", "128.180")} />
</section>
<section className="hot_main">
<h4>{
props.nm}</h4>
{
(props.globalReleased && sc()) || wish()}
<p>主演:{
props.star}</p>
<p>{
props.showInfo}</p>
</section>
<section className="hot_state">
<Button
inline
size="small"
type={
(props.globalReleased && "warning") || "primary"}
>
{
(props.globalReleased && "购买") || "预售"}
</Button>
</section>
</article>
);
}
export default HotItem;
import React, {
Component } from "react";
import request from "../../utils/request.js";
import "./index.scss";
import CateList from "./cate_list.js";
export default class List extends Component {
constructor(props) {
super(props);
this.state = {
lists: []
};
}
async componentDidMount() {
//? 数据请求
//* 先发送数据请求,然后获得数据,然后赋值给我们组件的状态
const result = await request({
method: "get",
url: "/index.php",
params: {
r: "class/category",
type: 1
}
});
this.setState({
lists: result.data.data.data
});
}
render() {
let {
lists } = this.state;
return (
<article id="list">
<CateList lists={
lists}></CateList>
</article>
);
}
}
然后进行多层数据 渲染
import React, {
Component } from "react";
import {
Tabs } from "antd-mobile";
import {
Link } from "react-router-dom";
export default class CateList extends Component {
renderList = list => {
//todo 渲染每一个最小的 元素
return list.map(item => (
<li key={
item.api_cid} className="list_item">
<Link
to={
{
pathname: `/category/${
item.api_cid}`,
search: `?cid=${
item.api_cid}`
}}
>
<img src={
item.img} />
<span>{
item.name}</span>
</Link>
</li>
));
};
renderFloors = floors => {
//todo 渲染主内容中的每一个楼层结构
return floors.map((item, index) => (
<section key={
index} className="list_floor">
<h3>
{
item.name} <Link to={
item.label_url}>{
item.label_name}</Link>
</h3>
<ul>{
this.renderList(item.list)}</ul>
</section>
));
};
renderContent = (
tab // todo 渲染每条数据的主要内容
) => (
<article
style={
{
padding: "0.1rem .2rem",
height: "100%",
backgroundColor: "#fff"
}}
>
<section className="list_banner">
<a href={
tab.banner_url} style={
{
display: "block", width: "100%" }}>
<img src={
tab.banner_img} style={
{
width: "100%" }} />
</a>
</section>
{
this.renderFloors(tab.floors)}
</article>
);
render() {
let lists = this.props.lists;
lists.map(item => {
//* 给每一个数据添加title 属性
item.title = item.name;
});
// console.log("张浩雨: CateList -> render -> lists", lists)
const tabs = lists; //? tabs 为数据
return (
<article id="category_list">
<Tabs
tabs={
tabs}
tabBarPosition="left"
tabDirection="vertical"
renderTabBar={
props => <Tabs.DefaultTabBar {
...props} page={
13} />}
>
{
this.renderContent}
</Tabs>
</article>
);
}
}
进行反向代理
// > src/setupProxy.js文件
//! 这个文件就是反向代理的配置文件
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
//* app.use( proxy(标识符,配置))
app.use(
proxy("/ajax", {
target: "http://m.maoyan.com",
changeOrigin: true
})
);
app.use(
proxy("/index.php", {
target: "http://www.qinqin.net",
changeOrigin: true
})
);
};
实现长列表滚动
BetterScroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的
布局要求
<div class="wrapper">
<ul class="content">
<li>...li>
<li>...li>
...
ul>
div>
上面的代码中 BetterScroll 是作用在外层 wrapper 容器上的,滚动的部分是 content 元素。这里要注意的是,BetterScroll 只处理容器(wrapper)的第一个子元素(content)的滚动,其它的元素都会被忽略。
实例化要求
最简单的初始化代码如下:
import BScroll from "@better-scroll/core";
let wrapper = document.querySelector(".wrapper");
let scroll = new BScroll(wrapper);
案例
//! movies > index.js
import React, {
Fragment, useEffect } from "react";
import MoviesHot from "./movie_hot";
import MoviesComming from "./movies_commint";
import MoviesNav from "./movies_nav";
import {
Route, Redirect } from "react-router-dom";
import BScroll from "better-scroll";
import "./index.scss";
function MoviesContainer() {
useEffect(() => {
setTimeout(() => {
new BScroll(document.querySelector("#moviescontainer"), {
click: true // todo 这里的意思是点击去除遮罩层
});
}, 0);
});
return (
<Fragment>
<MoviesNav></MoviesNav>
<article id="moviescontainer">
<Redirect from="/home" to="/home/movies_hot"></Redirect>
<Route path="/home/movies_hot" component={
MoviesHot}></Route>
<Route path="/home/movies_comming" component={
MoviesComming}></Route>
</article>
</Fragment>
);
}
export default MoviesContainer;
以上两个形式都可以,但是如果写了/:id之后,路径必须全跟
举例: http://localhost:3000/list/001?a=1&b=2
路由传参
src > router > index.js;
import React, {
useState } from "react";
import {
Route, Switch, Redirect } from "react-router-dom";
import Home from "../views/home";
import Category from "../views/category";
import Shopcar from "../views/shopcar";
import Mine from "../views/mine";
import List from "../views/list";
function RouterComp() {
const [routes] = useState([
{
id: 1,
path: "/home",
component: Home
},
{
id: 2,
path: "/category/:id", //todo 定位
component: Category
},
{
id: 3,
path: "/shopcar",
component: Shopcar
},
{
id: 4,
path: "/mine",
component: Mine
},
{
id: 5,
path: "/list",
component: List
}
]);
function renderRoutes() {
return routes.map(item => (
<Route
key={
item.id}
path={
item.path}
component={
item.component}
exact={
item.exact}
></Route>
));
}
return (
//* Route是一个路由展示组件,通过component属性来确定渲染哪一个组件
//* Switch组件一次只渲染一个Route
// * 可以实现类似按需加载组件的作用,可以起到一定的性能优化作用
//* exact 是路由完全匹配
//* Redirect 是重定向组件 from 来源 to 目标 / /home
//
<Switch>
<Redirect from="/" to="/home" exact></Redirect>
{
renderRoutes()}
{
/* <Router path="/home" component={
Home} exact=></Router> */}
</Switch>
//{/* */}
//
);
}
export default RouterComp;
// > src > views> list > cate_list.js
import React, {
Component } from "react";
import {
Tabs } from "antd-mobile";
import {
Link } from "react-router-dom";
export default class CateList extends Component {
renderList = list => {
//todo 渲染每一个最小的 元素
return list.map(item => (
<li key={
item.api_cid} className="list_item">
<Link
to={
{
pathname: `/category/${
item.api_cid}`, // todo 定位
search: `?cid=${
item.api_cid}` // todo 定位
}}
>
<img src={
item.img} />
<span>{
item.name}</span>
</Link>
</li>
));
};
renderFloors = floors => {
//todo 渲染主内容中的每一个楼层结构
return floors.map((item, index) => (
<section key={
index} className="list_floor">
<h3>
{
item.name} <Link to={
item.label_url}>{
item.label_name}</Link>
</h3>
<ul>{
this.renderList(item.list)}</ul>
</section>
));
};
renderContent = (
tab // todo 渲染每条数据的主要内容
) => (
<article
style={
{
padding: "0.1rem .2rem",
height: "100%",
backgroundColor: "#fff"
}}
>
<section className="list_banner">
<a href={
tab.banner_url} style={
{
display: "block", width: "100%" }}>
<img src={
tab.banner_img} style={
{
width: "100%" }} />
</a>
</section>
{
this.renderFloors(tab.floors)}
</article>
);
render() {
let lists = this.props.lists;
lists.map(item => {
//* 给每一个数据添加title 属性
item.title = item.name;
});
// console.log("张浩雨: CateList -> render -> lists", lists)
const tabs = lists; //? tabs 为数据
return (
<article id="category_list">
<Tabs
tabs={
tabs}
tabBarPosition="left"
tabDirection="vertical"
renderTabBar={
props => <Tabs.DefaultTabBar {
...props} page={
13} />}
>
{
this.renderContent}
</Tabs>
</article>
);
}
}
路由接参
import React, {
useState, useEffect } from "react";
import "./index.scss";
import {
Route, NavLink, Redirect } from "react-router-dom";
import Picture from "./children/picture";
import Text from "./children/text";
import Comment from "./children/comment";
import request from "../../utils/request";
import axios from "axios";
function Category(props) {
const [navLink] = useState([
{
id: 1,
text: "图片",
path: "/category/picture"
},
{
id: 2,
text: "文字",
path: "/category/text"
},
{
id: 3,
text: "评论",
path: "/category/comment"
}
]);
let [detail, setDetail] = useState([]);
let [cid, setCid] = useState(22);
function renderNavLink() {
return navLink.map(item => {
return (
<NavLink to={
item.path} key={
item.id}>
{
item.text}
</NavLink>
);
});
}
useEffect(() => {
let id =
props.location.pathname
.slice(0)
.split("/")
.pop() || 22; //todo 定位
console.log("张浩雨: Category -> id", id);
setCid((cid = id));
setTimeout(() => {
if (detail.length) {
return;
} else {
axios
.get("/index.php", {
params: {
r: "class/cyajaxsub",
page: 1,
cid: cid,
px: "t"
}
})
.then(ret => {
console.log(ret.data.data.content);
setDetail((detail = ret.data.data.content));
});
}
}, 0);
});
return (
<article className="category-box">
<section className="category-nav">{
renderNavLink()}</section>
<section className="category-main">
<h3>列表</h3>
{
/* */}
<Route path="/category/picture" component={
Picture}></Route>
<Route path="/category/text" component={
Text}></Route>
<Route path="/category/comment" component={
Comment}></Route>
</section>
</article>
);
}
export default Category;