前言
根据自己所学的技术,整合起来模仿一个网站的页面。
所要仿的页面网站:ONE·一个
所用到的技术
-
React:前端框架,官网地址
-
react-router-dom:路由管理,官网地址
-
mockjs:模拟数据,官网地址
-
axios:请求数据,官网地址
-
antd:UI组件库,官网地址
-
moment:时间格式转换,官网地址
开始
准备一个项目:npx create-react-app mproject-one
安装上述中除React以外的全部技术 npm i xxx(名字即可) -save
项目结构
- src
assets
: 静态资源文件,存放图片啥的
components
: 常用组件
mock
:数据模拟
page
:路由组件
route
: 路由管理
...
项目页面分析
拆分组件:
- 整体页面
- 内容部分
分析并且拆解完组件之后,紧接着就是对每一模块的组件的代码编写
数据的模拟和获取
当页面编写完成,需要有数据显示才能更好的来调整页面的样式,因此这里我选择使用mock+axios来模拟数据和获取数据
模拟数据
新建一个mock文件夹,以及在该文件夹中新建一个index.js文件
import Mock, { Random } from 'mockjs'
//获取文章的数据
Mock.mock('api/articles', 'get', () => {
return {
status: 200,
message: '获取文章成功',
list: Mock.mock({
'articlesList|7': [
{
"id|+1": 1,
"title": '@ctitle(5, 15)',
"content": '@cparagraph(500,1000)',
"time": '@date()',
"brief": "@csentence(10,15)",
"author": '@cname()',
"principal": '@name()',
"img_url": Random.image('566x377', '#50B347', '#FFF', ' Hello')
}
]
}),
}
})
//获取问题的数据
Mock.mock('api/problems', 'get', () => {
return {
status: 200,
message: '获取问题成功',
list: Mock.mock({
'problemsList|7': [
{
"id|+1": 1,
"problem": '@ctitle(5, 15)',
"principal": '@name()',
"answerList|10-20": [
{
"aid|+1": 1,
"content": '@cparagraph()',
"name": '@cname()',
}
],
}
]
}),
}
})
再在入口文件index.js中引入上面的mock文件,即:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
//引入mock文件
import "./mock/index"
ReactDOM.render(
<App />
, document.getElementById("root"));
获取数据
在文章组件中引入axios,在通过mock的url来获取数据
import React, { useEffect, useState } from "react";
import "./index.css";
import axios from "axios";
import Content from "../../../component/Content";
export default function Articles() {
const [articlesList, setArticlesList] = useState([]);
//组件第一次渲染时获取数据
useEffect(() => {
axios.get("api/articles").then((res) => {
setArticlesList(res.data.list.articlesList);
});
}, []);
//此处为后续的组件封装
return <Content title="ONE 文章" dataList={articlesList} />;
}
公共组件提取
可以看出文章和问题两个组件样子很相似,此时我们就可以将它们提取出来形成一个公共组件,再分别在相对应的组件中传递数据给这个公共组件即可。
公共组件:
import React from "react";
import { Link } from "react-router-dom";
export default function Contents(props) {
//需要传递标题名和数据
const { title, dataList } = props;
return (
<>
<div className="articles">
<h4 className="title">{title}</h4>
<div>
{dataList.map((item, index) =>
index === 0 ? (
<div className="firstArticle" key={item.id}>
<p className="firstArticle_id">VOL.{item.id}</p>
<p className="firstArticle_title">
<Link to={`/problem/${item.id}`} state={{ item }}>
{item.problem}
</Link>
</p>
</div>
) : (
<li key={item.id}>
<span>VOL.{item.id}</span>
<Link to={`/problem/${item.id}`} state={{ item }}>
{" "}
{item.problem}
</Link>
</li>
)
)}
</div>
</div>
</>
);
}
文章组件:
//导入公共组件
import Contents from "../../../component/Contents";
//将所需要的数据传给公共组件
<Contents title="ONE 文章" dataList={articlesList} />
问题组件也是如此
路由方面
现在直接安装react-router-dom是6.x版本,在这个版本上更改了一些API也增加了一些API,详情请看我之前写的博客React---路由
分析
-
点击页面跳转之后该在何处显示?
-
需要编写路由有哪些?
-
是否存在子级路由?
根据分析的这些,可以得出结论:
-
点击跳转之后页面是显示在内容部分的,头部和尾部不需要动
-
路由都只是一级路由,可根据原页面的跳转链接来编写路由
代码编写
- 创建route文件夹并且在该文件夹中创建index.js文件,来编写路由表
//引入匹配的路径之后需要跳转显示的组件
import Middle from '../page/Middle'
import ArticleDetail from '../page/Details/Article'
import ProblemDetail from '../page/Details/Problem'
import PictureDetail from '../page/Details/Picture'
import Acercade from '../page/Acercade'
import { Navigate } from 'react-router-dom'
import Politica from '../page/Politica'
import Contacto from '../page/Contacto'
const routes = [
{
path: '/',
element: <Middle />
},
{
path: '/article/:id',
element: <ArticleDetail />
},
{
path: '/problem/:id',
element: <ProblemDetail />
},
{
path: '/one/:id',
element: <PictureDetail />
},
{
path: '/acercade',
element: <Acercade />
},
{
path: '/politica',
element: <Politica />
},
{
path: '/contacto',
element: <Contacto />
},
{
path: '/',
element: <Navigate to="/" />
}
]
export default routes
- 在APP.jsx中使用useRoutes来根据路由表,来动态创建
<Routes>
和<Route>
import React from "react";
import Head from "./page/Head";
import Foot from "./page/Foot";
import "./App.css";
import { useRoutes } from "react-router-dom";
import routes from "./route";
import { Layout } from "antd";
const { Header, Footer, Content } = Layout;
export default function App() {
const element = useRoutes(routes);
return (
<>
<Layout>
<Header>
<Head />
</Header>
<Content>{element}</Content>
<Footer>
<Foot />
</Footer>
</Layout>
</>
);
}
- 最后再将代码中的a标签换为Link标签,并且将href换为to以及其对应的路径