前端技术总结

前端技术

一、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 函数调用)。
  • 关键语法
    • 只能返回单个根元素(多元素需用 divReact.Fragment(简写 <>)包裹)。
    • 属性用驼峰命名(如 className 替代 classonClick 替代 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 中使用。
  • 只能在组件顶层调用(不能嵌套在 iffor 或其他函数中)。

2. 常用 Hook

(1)useState(状态管理)
  • 见上文“状态管理”部分,支持基本类型、对象、数组等状态。
  • 对象状态更新:需返回新对象(避免直接修改原对象):
    const [user, setUser] = useState({ name: "Bob", age: 30 });
    // 正确更新:保留原有属性,只修改age
    setUser(prev => ({ ...prev, age: prev.age + 1 }));
    
(2)useEffect(副作用管理)
  • 定义:处理组件渲染后的“副作用”(如数据请求、事件监听、DOM 操作等),等效于类组件的 componentDidMountcomponentDidUpdatecomponentWillUnmount
  • 语法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(引用与持久化数据)
  • 两大作用
    1. 访问 DOM 元素
      const inputRef = useRef(null);
      // 聚焦输入框
      const focusInput = () => inputRef.current.focus();
      // JSX 中绑定:<input ref={inputRef} />
      
    2. 保存跨渲染的数据(更新不会触发组件重新渲染):
      const prevCountRef = useRef();
      // 保存上一次的count值
      useEffect(() => {
        prevCountRef.current = count;
      });
      
(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.lazySuspense 按需加载组件:
    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% 开发时间)
⑥ 核心优势总结
特性UmiAnt Design Pro
定位企业级前端框架中后台脚手架(基于 Umi)
路由约定式/配置式路由继承 Umi 路由,支持复杂权限路由
状态管理useModel 轻量方案基于 useModel,预设全局状态(用户、配置)
UI 组件需手动引入 Antd内置 Antd + ProComponents 高级组件
适用场景灵活定制项目标准化中后台系统(快速开发)
学习成本中等(需掌握路由、插件机制)低(预设方案,按文档开发即可)

十二、React 18+ 新特性(进阶)

  • 并发渲染:允许中断、暂停、恢复渲染,提升用户体验。
  • 自动批处理:合并多个状态更新,减少渲染次数。
  • Transitions:区分紧急更新(如输入)和非紧急更新(如列表过滤)。
  • Server Components:服务器端渲染组件,减少客户端 JS 体积。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值