需要进行判断,否则会进行多次数据请求
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>
<!-- 这里可以放一些其它的 DOM,但不会影响滚动 -->
</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;
<Route path = “/list” component = { List }/>
<Route path = “/list/:id” component = { List }/>
以上两个形式都可以,但是如果写了/: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
// <BrowserRouter>
<Switch>
<Redirect from="/" to="/home" exact></Redirect>
{renderRoutes()}
{/* <Router path="/home" component={Home} exact=></Router> */}
</Switch>
//{/* </BrowserRouter> */}
// <Home></Home>
);
}
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>
{/* <Redirect from="/category" to="/category/text" exact></Redirect> */}
<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;