前言
React是用于构建用户界面的JavaScript库,起源于FaceBook的内部项目,那么什么是组件化呢?组件化的核心思想就是提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。任何的应用都会被抽象成一颗组件树。有了组件化的思想,我们在之后的开发中就要充分的利用它,尽可能的将页面拆分成一个个小的,可复用的组件。这样让我们的代码更加方便组织和管理,并且扩展性也更强。
正好赶上Steam的夏促活动,而我一般使用小黑盒这款移动端app查看优惠(背刺)信息,于是就想着能不能自己动手使用React开发一个类似小黑盒的界面来锻炼自己组件开发的能力。
页面展示
项目准备
技术栈
- Html, CSS, JavaScript 三剑客
- antd-mobile 一个由由蚂蚁金融团队推出的一个开源的react组件库
- axios 用于请求后端api数据
- classnames 能方便动态切换 class 名称
- font-awesome 一个图标字体库
- swiper 一款轻量级的轮播图插件
- react react-router react-router-dom 路由组件
创建React项目
要想快速上手React项目,一个好的React脚手架是必不可少的。以下是我创建脚手架的方式
npm init @vitejs/app
我选用这种方式的主要原因就是快
这种方式相对于传统的方式分家的简单和直接,是目前最快的脚手架
项目架构
|--xiaoheihe
| |--index.html
| |--js
| | └──adapter.js
| |--src
| | |--api
| | | └──request.js
| | |--assets
| | | └──styles
| | | └──reset.css
| | |--components
| | | └──Cutover
| | |--pages
| | | ├──All
| | | ├──AllDetail
| | | └──Talk
| | |--routers
| | | └──index.jsx
| | |--utile
| | | └──index.jsx
| | |--App.css
| | |--App.jsx
| | |--main.jsx
| | |--vite.config.js
功能展示
axios数据请求
为了更加真实的模拟前端从后端得到数据,这里使用了axios + fastmock ,axios是一个基于 promise的网络请求库。在fastmock中的数据格式为json。
import axios from "axios";
export const getGamelist = () =>
axios.get('https://www.fastmock.site/mock/512b4836dc5819d9a02a2eb6c8bd971a/xiaoheihe/gamelist')
自适应
作为一个移动端的项目,在页面开发过程中要注意不同设备屏幕大小的适配问题,所以需要自适应来进行配置,我选择的方案是20px=1rem
var init = function () {
var clientWidth = document.documentElement.clientWidth || document.body.clientWidth;
if (clientWidth >= 640) {
clientWidth = 640;
}
var fontSize = 20 / 375 * clientWidth;
document.documentElement.style.fontSize = fontSize + "px";
}
init();
window.addEventListener("resize", init);
配置路由
在整个项目中有许多页面需要进行跳转,所以需要配置路由,我选择在src目录下创建一个routes文件夹,在里面的index.jsx文件中配置整个项目的所有路由。这样做对后期的路由维护更加友好,避免了所有路由都在堆积在App.jsx文件里面的不利于维护的现象。并且我对其他非主页路由进行了路由懒加载的设置,在一定的程度上进行了性能优化。
// 路由独立配置文件
import { useState, lazy } from 'react'
import { Routes, Route, Link} from 'react-router-dom'
import All from '../pages/All'
const Talk = lazy(() => import('../pages/Talk'))
const AllDetail = lazy(() => import('../pages/AllDetail'))
import { Navigate } from 'react-router'
const RoutesConfig = () => {
return (
<>
<Routes>
<Route path='/' element={<Navigate to="/all" replace={true} />} />
<Route path='/all' element={<All />}></Route>
<Route path='/talk' element={<Talk />}></Route>
<Route path='/alldetali/:id' element={<AllDetail />}></Route>
</Routes>
</>
)
}
export default RoutesConfig
在app.jsx文件中引入该配置
import RoutesConfig from './routes'
function App() {
return (
<div className="App">
...
<RoutesConfig />
...
</div>
)
}
export default App
首页Tab跳转
- 使用useLocation,它返回包含有关当前URL的信息的位置对象。每当URL更改时,都会返回一个新的位置对象。
- 使用classnames, 将路径做为类名是否发生改变的条件,当路径改变后,对应的字体加粗,以及增加下边框。
...
const { pathname } = useLocation()
...
className={classnames('nav-item' ,{jihuo:pathname == item.path })}
...
weiper轮播图
使用了swiper这一款轻量级的轮播图插件,能够快速的制作出一个轮播图
// 为了避免一些错误我这里安装了4.5.0版本的swiper
// 安装
npm i swiper@4.5.0
// 引入
import Swiper from 'swiper'
// 使用生命周期函数完成swiper配置
useEffect(() => {
new Swiper('.all_banners', {
loop: true,
autoplay: true,
pagination: {
el:'.swiper-pagination'
}
})
},[])
正文页开发
loading状态
因为正文是通过首页文章点击进入的,需要进行网络请求,要花费一定时间,为了更好的用户体验,我增加了一个loading状态(还没有完善)。
NavBar
正文页面的头部NavBar我是使用antd-mobile组件库快速完成的。
// 安装 antd-mobile
npm i antd-mobile
// 引入 antd-mobile
import { NavBar } from 'antd-mobile'
// 具体实现代码
<NavBar
back='返回'
onBack={() => navigate(-1)}
>
正文
</NavBar>
底部图标
使用了font-awesome图标字体库,用onClick监测是否点击,如果点击则将图标和字体的颜色变为黑色,没错,这里的样式改变使用的也是classnames
总结
这是我第一个react项目,虽然只完成了一部分,但是终究是迈出了react开发的第一步,后面也会继续完善这个项目,如果有错误欢迎各位指出。希望这篇文章能够帮助到像我一样正在学习react的同学们。