前端技术
一、React 基础与工程搭建
1. 核心概念入门
- 什么是 React:React 是一个用于构建用户界面的 JavaScript 库,核心思想是组件化和声明式编程(关注“是什么”而非“怎么做”)。
- 虚拟 DOM(Virtual DOM):React 内部维护的内存中的 DOM 映射,通过对比虚拟 DOM 的差异(Diffing 算法),只更新真实 DOM 中变化的部分,提升性能。
2. 工程搭建与基础操作
- 创建工程:
npx create-react-app my-app # 官方脚手架创建工程 cd my-app npm start # 启动开发服务器(默认端口3000) - 工程目录结构:
src/:源码目录(组件、逻辑、样式等)public/:静态资源(HTML 模板、图标等,打包时原样复制)package.json:依赖管理和脚本配置
二、JSX 语法与组件基础
1. JSX 核心规则
- 定义:JSX 是 JavaScript 的语法扩展,允许在 JS 中编写类似 HTML 的结构(最终会被 Babel 编译为 React 函数调用)。
- 关键语法:
- 只能返回单个根元素(多元素需用
div或React.Fragment(简写<>)包裹)。 - 属性用驼峰命名(如
className替代class,onClick替代onclick)。 - 插值使用
{}:可嵌入变量、函数调用、对象等(如<div>{user.name}</div>)。 - 样式定义:通过对象形式(如
<div style={{ color: 'red', fontSize: '16px' }}>)。
- 只能返回单个根元素(多元素需用
2. 组件定义与命名
- 命名规范:
- 组件名必须以大写字母开头(如
UserCard),HTML 标签以小写开头(如div)。
- 组件名必须以大写字母开头(如
- 组件类型:
- 函数组件(推荐):
function Welcome() { return <h1>Hello React</h1>; } - 类组件(传统方式):需继承
React.Component并实现render()方法:import React from 'react'; class Welcome extends React.Component { render() { return <h1>Hello React</h1>; } }
- 函数组件(推荐):
三、组件通信与数据传递(Props)
1. Props 基础
- 定义:Props 是组件间传递数据的只读对象(“父传子”的主要方式),子组件不能直接修改 props。
- 用法:
// 父组件 function Parent() { const user = { name: "Alice", age: 25 }; return <Child user={user} />; } // 子组件 function Child(props) { return <div>{props.user.name} ({props.user.age}岁)</div>; } - 展开 Props:通过
...简化多属性传递:<Child {...user} /> // 等价于 <Child name={user.name} age={user.age} />
2. 组件内容传递(children 属性)
- 用于传递组件的“子内容”(类似 HTML 标签的嵌套内容):
function Container(props) { return <div className="container">{props.children}</div>; // 渲染传入的子内容 } // 使用 <Container> <p>这是容器内的内容</p> </Container>
四、状态管理(State)与事件处理
1. 状态(State)基础
- 定义:组件内部的可变数据,状态变化会触发组件重新渲染。
- 函数组件中的状态(useState):
import { useState } from 'react'; function Counter() { // 声明状态变量:count(当前值)和 setCount(更新函数) const [count, setCount] = useState(0); // 初始值为0 return ( <div> <p>计数:{count}</p> <button onClick={() => setCount(count + 1)}>加1</button> </div> ); }- 注意:不能直接修改状态(如
count++无效),必须通过setXxx方法更新。
- 注意:不能直接修改状态(如
2. 事件处理
- 基本语法:事件名采用驼峰命名(如
onClick),绑定函数(而非字符串)。function Button() { const handleClick = () => { console.log("按钮被点击"); }; return <button onClick={handleClick}>点击我</button>; // 注意:无括号 } - 传递参数:通过箭头函数包裹:
<button onClick={() => handleClick("参数")}>传递参数</button>
五、React Hooks 核心(函数组件进阶)
1. Hooks 规则
- 只能在函数组件或自定义 Hook 中使用。
- 只能在组件顶层调用(不能嵌套在
if、for或其他函数中)。
2. 常用 Hook
(1)useState(状态管理)
- 见上文“状态管理”部分,支持基本类型、对象、数组等状态。
- 对象状态更新:需返回新对象(避免直接修改原对象):
const [user, setUser] = useState({ name: "Bob", age: 30 }); // 正确更新:保留原有属性,只修改age setUser(prev => ({ ...prev, age: prev.age + 1 }));
(2)useEffect(副作用管理)
- 定义:处理组件渲染后的“副作用”(如数据请求、事件监听、DOM 操作等),等效于类组件的
componentDidMount、componentDidUpdate、componentWillUnmount。 - 语法:
useEffect(回调函数, 依赖数组)- 依赖数组为空
[]:仅在组件挂载时执行一次(初始化)。 - 依赖数组有值:组件挂载时执行,且依赖变化时重新执行。
- 无依赖数组:每次渲染后都执行。
- 依赖数组为空
- 示例:组件挂载时请求数据,卸载时清理:
import { useEffect, useState } from 'react'; function DataFetcher() { const [data, setData] = useState(null); useEffect(() => { // 副作用:请求数据 const fetchData = async () => { const res = await fetch("https://api.example.com/data"); setData(await res.json()); }; fetchData(); // 清理函数:组件卸载时执行(如取消请求、移除监听) return () => { // 示例:取消未完成的请求 }; }, []); // 空依赖:仅执行一次 return <div>{data ? data.name : "加载中..."}</div>; }
(3)useRef(引用与持久化数据)
- 两大作用:
- 访问 DOM 元素:
const inputRef = useRef(null); // 聚焦输入框 const focusInput = () => inputRef.current.focus(); // JSX 中绑定:<input ref={inputRef} /> - 保存跨渲染的数据(更新不会触发组件重新渲染):
const prevCountRef = useRef(); // 保存上一次的count值 useEffect(() => { prevCountRef.current = count; });
- 访问 DOM 元素:
(4)useContext(跨组件通信)
- 用于跨层级组件通信(避免 Props 层层传递):
// 1. 创建Context const ThemeContext = React.createContext(); // 2. 上层组件提供数据 function App() { const [theme, setTheme] = useState("light"); return ( <ThemeContext.Provider value={{ theme, setTheme }}> <Child /> </ThemeContext.Provider> ); } // 3. 深层组件消费数据 function Child() { const { theme, setTheme } = useContext(ThemeContext); return ( <button onClick={() => setTheme("dark")}> 当前主题:{theme} </button> ); }
3. 自定义 Hook(逻辑复用)
- 定义:封装可复用的逻辑,命名以
use开头(如useLocalStorage)。 - 示例:封装本地存储逻辑:
function useLocalStorage(key, initialValue) { // 从localStorage读取初始值 const [value, setValue] = useState(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initialValue; }); // 更新时同步到localStorage useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue]; } // 使用:在组件中复用 function UserSettings() { const [name, setName] = useLocalStorage("username", ""); return <input value={name} onChange={(e) => setName(e.target.value)} />; }
六、组件通信进阶
1. 子传父通信
- 核心:父组件传递一个回调函数给子组件,子组件调用该函数传递数据。
// 父组件 function Parent() { const [message, setMessage] = useState(""); const handleChildData = (data) => setMessage(data); // 接收子组件数据 return <Child onSendData={handleChildData} />; } // 子组件 function Child({ onSendData }) { return <button onClick={() => onSendData("来自子组件")}>发送</button>; }
2. 同级组件通信
- 通过父组件中转实现(子 A → 父 → 子 B):
function App() { const [sharedData, setSharedData] = useState(""); return ( <div> <ChildA onSend={(data) => setSharedData(data)} /> // 子A传值给父 <ChildB data={sharedData} /> // 父传值给子B </div> ); }
七、列表与表单处理
1. 列表渲染
- 使用
map遍历数组,必须指定key(唯一标识,提升 Diff 性能):const users = [ { id: 1, name: "Alice" }, { id: 2, name: "Bob" } ]; function UserList() { return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> // key必须唯一(推荐用id) ))} </ul> ); }
2. 表单处理
(1)受控组件
- 表单元素的值由 React 状态控制(
value绑定状态,onChange更新状态):function LoginForm() { const [username, setUsername] = useState(""); return ( <input value={username} // 状态控制值 onChange={(e) => setUsername(e.target.value)} // 更新状态 /> ); }
(2)非受控组件
- 表单元素的值由 DOM 自身控制(通过
useRef访问值):function LoginForm() { const inputRef = useRef(null); const handleSubmit = () => { console.log("输入值:", inputRef.current.value); // 直接从DOM获取值 }; return ( <div> <input ref={inputRef} /> <button onClick={handleSubmit}>提交</button> </div> ); }
八、路由管理(react-router-dom)
1. 核心作用
- 实现单页应用(SPA)的路由跳转(无需刷新页面,通过修改 URL 切换组件)。
2. 安装与基础用法
-
安装:
npm install react-router-dom@6 # 推荐v6版本 -
核心组件:
BrowserRouter:路由容器(包裹整个应用)。Routes:路由集合(类似switch,匹配第一个符合的路由)。Route:定义路由规则(path路径,element对应组件)。Link:路由跳转(类似<a>,但无刷新)。
-
示例:
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'; function Home() { return <h1>首页</h1>; } function About() { return <h1>关于页</h1>; } function App() { return ( <BrowserRouter> <nav> <Link to="/">首页</Link> | <Link to="/about">关于</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </BrowserRouter> ); }
3. 路由 Hook
useParams:获取路径参数(如/user/:id中的id)。useNavigate:编程式导航(如按钮点击跳转):const navigate = useNavigate(); // 跳转到/about const goToAbout = () => navigate("/about");
九、状态管理进阶(全局状态)
1. 为什么需要全局状态
- 当多个组件(跨层级、无直接关系)需要共享状态时(如用户信息、主题设置),Context + useReducer 或第三方库更高效。
2. useReducer(复杂状态逻辑)
- 用于管理复杂状态(如多值关联、复杂更新逻辑),类似 Redux 的简化版:
// 1. 定义reducer(纯函数:接收状态和动作,返回新状态) function counterReducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: return state; } } // 2. 在组件中使用 function Counter() { const [state, dispatch] = useReducer(counterReducer, { count: 0 }); return ( <div> <p>计数:{state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>加1</button> </div> ); }
3. 第三方状态管理库(可选)
- Redux:老牌状态管理库,适合大型应用(需配合
react-redux)。 - Zustand:轻量级库,API 简洁(推荐中小型应用)。
十、性能优化
1. 减少不必要的渲染
- React.memo:缓存函数组件( props 不变时不重新渲染):
const MemoizedComponent = React.memo(ChildComponent); - useMemo:缓存计算结果(避免每次渲染重复计算):
const expensiveResult = useMemo(() => computeExpensiveValue(a, b), [a, b]); - useCallback:缓存函数(避免子组件因函数引用变化而重新渲染):
const handleClick = useCallback(() => { /* 逻辑 */ }, [deps]);
2. 其他优化
- 列表渲染优化:使用
key且避免用索引作为key。 - 懒加载组件:通过
React.lazy和Suspense按需加载组件:const LazyComponent = React.lazy(() => import('./LazyComponent')); // 使用:<Suspense fallback={<div>加载中...</div>}><LazyComponent /></Suspense>
十一、工程化工具与生态
1. Umi 框架
① 什么是 Umi
Umi 是一个基于 React 的企业级前端框架,由阿里蚂蚁集团开发维护,具备路由自动生成、内置构建工具、插件化机制等特性,专注于提升中大型前端项目的开发效率。
核心优势:
- 开箱即用,整合 React、React Router、Babel 等工具链
- 支持约定式路由(文件即路由)和配置式路由
- 内置权限管理、数据流方案、请求库等企业级功能
- 基于 Webpack 构建,支持热更新、代码分割、Tree-Shaking 等优化
② Umi 安装与初始化
# 安装 Umi CLI
npm install umi -g
# 初始化项目
mkdir my-umi-app && cd my-umi-app
umi init
# 启动开发服务器(默认端口 8000)
npm run dev
# 构建生产环境
npm run build
③ 核心特性与用法
Ⅰ. 路由系统
Umi 支持约定式路由(推荐)和配置式路由,无需手动编写 react-router-dom 代码。
-
约定式路由:
页面文件按目录结构自动生成路由,例如:src/pages/ ├── index.js → 路径:/ ├── about.js → 路径:/about ├── user/ │ ├── index.js → 路径:/user │ └── [id].js → 路径:/user/:id(动态路由) -
配置式路由:
在config/routes.js中手动配置路由(覆盖约定式路由):export default [ { path: '/', component: './index' }, { path: '/about', component: './about' }, { path: '/user/:id', component: './user/[id]' }, ];
Ⅱ. Umi Request(HTTP 请求工具)
基于 fetch 封装的请求库,支持拦截器、错误处理、超时控制等。
import { request } from 'umi';
// GET 请求(带参数)
request.get('/api/user', { params: { id: 1 } })
.then(res => console.log(res))
.catch(err => console.error(err));
// POST 请求(带数据)
request.post('/api/user', { data: { name: 'Alice' } });
// 拦截器配置(全局)
request.interceptors.request.use((url, options) => {
// 添加 Token 到请求头
return {
url,
options: { ...options, headers: { Authorization: 'token' } },
};
});
Ⅲ. useModel(状态共享)
Umi 内置的状态管理方案,用于跨组件共享状态,替代部分 Redux 场景。
-
定义模型:在
src/models/目录下创建模型文件(如user.js):export default function userModel() { const [userInfo, setUserInfo] = useState(null); // 登录方法 const login = async (params) => { const res = await request.post('/api/login', { data: params }); setUserInfo(res.data); }; return { userInfo, login, // 暴露方法供组件调用 }; } -
在组件中使用:
import { useModel } from 'umi'; function Profile() { const { userInfo, login } = useModel('user'); // 引用模型 return ( <div> {userInfo ? userInfo.name : <button onClick={() => login({ username: 'admin' })}>登录</button>} </div> ); }
Ⅳ. 权限管理
Umi 内置权限控制,通过 src/access.js 定义权限规则,在路由或组件中使用。
-
定义权限(
src/access.js):export default function access(initialState) { const { userInfo } = initialState || {}; return { canRead: true, // 所有人可读取 canEdit: userInfo?.role === 'admin', // 仅管理员可编辑 }; } -
在路由中控制(
config/routes.js):{ path: '/admin', component: './admin', access: 'canEdit', // 仅 canEdit 为 true 时可见 } -
在组件中控制:
import { useAccess } from 'umi'; function AdminPanel() { const { canEdit } = useAccess(); return canEdit ? <button>编辑</button> : null; }
Ⅴ. 布局与全局配置
-
全局布局:在
src/layouts/index.js中定义全局布局(如侧边栏、顶部导航):export default function Layout({ children }) { return ( <div className="app-layout"> <Sidebar /> <main>{children}</main> {/* 页面内容会渲染到这里 */} </div> ); } -
配置文件:
config/config.js用于配置全局参数(端口、路由、主题等):export default { history: { type: 'hash' }, // 路由模式(hash 或 browser) devServer: { port: 8080 }, // 开发服务器端口 theme: { '@primary-color': '#1890ff' }, // 自定义 Antd 主题 };
2.Ant Design Pro 框架
① 什么是 Ant Design Pro
Ant Design Pro 是基于 Umi + Ant Design + ProComponents 的企业级中后台脚手架,提供完整的中后台解决方案,包含:
- 预设的页面布局(侧边栏、顶部导航、面包屑等)
- 常用业务组件(表格、表单、图表、权限管理等)
- 最佳实践代码规范和目录结构
② 安装与初始化
# 安装 Pro CLI
npm install @ant-design/pro-cli -g
# 创建项目
pro create my-pro-app
# 进入项目并启动
cd my-pro-app
npm install
npm run dev
③ 核心特性与目录结构
Ⅰ. 目录结构(精简版)
src/
├── api/ # API 接口定义(统一管理请求)
├── assets/ # 静态资源(图片、样式等)
├── components/ # 自定义业务组件
├── layouts/ # 布局组件(全局/页面布局)
├── models/ # 状态模型(useModel)
├── pages/ # 页面组件(约定式路由)
│ ├── Dashboard/ # 仪表盘页面
│ ├── User/ # 用户管理页面
│ └── Login.js # 登录页
├── utils/ # 工具函数
└── app.js # 应用入口配置
Ⅱ. 布局配置(app.js)
通过 app.js 自定义全局布局(覆盖默认布局):
export const layout = ({ initialState }) => {
return {
// 自定义顶部导航
headerRender: () => <CustomHeader />,
// 自定义页脚
footerRender: () => <Footer copyright="© 2024 My App" />,
// 路由切换时触发
onPageChange: (location) => {
console.log('路由变化:', location.pathname);
},
// 左侧菜单配置
menu: {
locale: false, // 关闭国际化
},
};
};
Ⅲ. ProComponents(增强组件库)
Ant Design Pro 内置 ProComponents,基于 Antd 封装的高级组件,简化中后台开发:
-
ProTable:高级表格,支持搜索、筛选、分页、批量操作等:
import { ProTable } from '@ant-design/pro-table'; const columns = [ { title: '姓名', dataIndex: 'name', key: 'name' }, { title: '年龄', dataIndex: 'age', key: 'age' }, ]; export default () => ( <ProTable columns={columns} request={async (params) => { // 对接接口,返回 { data: [], total: 0 } 格式 const res = await request('/api/users', { params }); return { data: res.list, total: res.total }; }} rowKey="id" search={true} // 显示搜索栏 /> ); -
ProForm:高级表单,支持联动、校验、保存草稿等:
import { ProForm, ProFormText } from '@ant-design/pro-form'; export default () => ( <ProForm onFinish={async (values) => { await request.post('/api/user', { data: values }); }} > <ProFormText name="name" label="姓名" rules={[{ required: true }]} /> <ProFormText name="age" label="年龄" /> </ProForm> ); -
其他组件:
ProCard(卡片)、ProLayout(布局)、ProDescriptions(详情展示)等。
Ⅳ. 权限与国际化
- 权限管理:基于 Umi 的
access.js,结合 ProComponents 的Access组件控制按钮/菜单权限。 - 国际化:内置
react-intl,支持多语言切换,翻译文件位于src/locales/目录。
Ⅴ. Mock 数据
Ant Design Pro 内置 Mock 功能,在 mock/ 目录下定义接口模拟数据,无需后端即可开发:
// mock/user.js
export default {
'GET /api/users': (req, res) => {
res.json({
list: [{ id: 1, name: '张三' }, { id: 2, name: '李四' }],
total: 2,
});
},
};
④ 部署与构建
- 开发环境:
npm run dev(热更新,使用 Mock 数据) - 测试环境:
npm run build:test(打包测试环境代码) - 生产环境:
npm run build(打包生产环境代码,输出到dist/目录) - 部署:将
dist/目录部署到 Nginx、CDN 或云服务器(需配置路由 fallback 指向index.html)。
⑤ Umi 与 Ant Design Pro 的关系与选择
- Umi 是基础框架,提供路由、构建、状态管理等核心能力,适合需要灵活定制的项目。
- Ant Design Pro 是基于 Umi 的脚手架,预设中后台最佳实践,适合快速开发标准化中后台系统。
选择建议:
- 若项目需要高度定制化 → 选 Umi
- 若开发企业级中后台(用户管理、数据看板等)→ 选 Ant Design Pro(开箱即用,节省 60% 开发时间)
⑥ 核心优势总结
| 特性 | Umi | Ant Design Pro |
|---|---|---|
| 定位 | 企业级前端框架 | 中后台脚手架(基于 Umi) |
| 路由 | 约定式/配置式路由 | 继承 Umi 路由,支持复杂权限路由 |
| 状态管理 | useModel 轻量方案 | 基于 useModel,预设全局状态(用户、配置) |
| UI 组件 | 需手动引入 Antd | 内置 Antd + ProComponents 高级组件 |
| 适用场景 | 灵活定制项目 | 标准化中后台系统(快速开发) |
| 学习成本 | 中等(需掌握路由、插件机制) | 低(预设方案,按文档开发即可) |
十二、React 18+ 新特性(进阶)
- 并发渲染:允许中断、暂停、恢复渲染,提升用户体验。
- 自动批处理:合并多个状态更新,减少渲染次数。
- Transitions:区分紧急更新(如输入)和非紧急更新(如列表过滤)。
- Server Components:服务器端渲染组件,减少客户端 JS 体积。
2990

被折叠的 条评论
为什么被折叠?



