前端开发基础(Java后端开发人员必备)

一、前端框架简介(从 Java 开发人员的视角理解)

1. React

核心概念

(1)组件化开发

  • React 就像 Java 的类或方法,可以把页面分成多个小模块(组件)。
  • 每个组件封装自己的逻辑和样式,像 Java 中一个专门处理功能的类。

简单类比:

  • Java 后端开发时,你可能会把用户逻辑写在一个 UserService 类中,负责用户相关的处理。
  • 在 React 中,页面中的按钮或表单等功能模块就是一个个“组件”。

示例:

const Button = ({ label }) => <button>{label}</button>;

(2)JSX

  • JSX 是 React 中的一种写法,允许直接在 JavaScript 里写 HTML。
  • 类似 Java 后端的模板引擎(如 Thymeleaf 或 JSP),但更灵活。

示例:

const Greeting = ({ user }) => (
  <div>
    {user ? <h1>Welcome, {user.name}!</h1> : <h1>Welcome, Guest!</h1>}
  </div>
);

(3)状态管理

  • React 的组件可以有“状态”,类似于 Java 对象里的属性,用来存储数据。
  • 使用 useState 定义状态,并动态更新界面,类似于 Java 的对象更新。

示例:

import { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
};
适合场景

React 适合用于构建动态交互多、页面复杂的项目,例如:

  • 后台管理系统:数据表格、图表展示、复杂的交互。
  • 电商系统前端:需要频繁更新界面的模块(如购物车、订单状态)。
文件类型

.jsx:

  • 写 React 组件代码,允许混合使用 HTML 和 JavaScript。

.tsx:

  • 和 .jsx 类似,但带有 TypeScript 的类型检查,更安全。

2. Vue.js

核心概念

(1)单文件组件

  • Vue 将一个页面模块(组件)的结构、样式和逻辑写在同一个 .vue 文件里。
  • 这种写法简单直观,便于开发和维护。

示例:

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  data() {
    return { message: 'Hello Vue!' };
  }
};
</script>

<style>
div {
  color: blue;
}
</style>

(2)双向绑定

  • Vue 提供了 v-model 指令,用来同步前端表单数据和后台数据。
  • 这有点像 Java 中 Bean 的 Getter 和 Setter 方法。

示例:

<template>
  <input v-model="message" />
  <p>{{ message }}</p>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  }
};
</script>

(3)渐进式

  • Vue 是一个“渐进式”框架,功能可以根据需求扩展。
    • Vue Router:处理页面跳转。
    • Vuex:管理全局数据(类似 Java 后端的全局变量)。
    • axios:用来调用后端 API。
适合场景

Vue 适合小型到中型项目,例如:

  • 快速开发的小应用:如一个用户信息录入页面。
  • 模块化功能的系统:例如嵌入式的表单或动态展示页面。
文件类型

.vue:

  • 包含 HTML 模板、CSS 样式和 JS 逻辑的单文件组件。

3. Angular

核心概念

(1)模块化开发

  • Angular 强制你将代码按照模块划分,比如用户管理模块、订单管理模块,类似 Java 的包划分。
  • 每个模块都可以独立开发和维护,类似于 Spring Boot 的微服务模块。

(2)TypeScript 支持

  • Angular 默认使用 TypeScript,类似于 Java 中的强类型语言。
  • 开发中可以明确定义变量和方法的类型,减少错误。

示例:

// 定义组件类
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent {
  userName: string = 'John Doe'; // 强类型
}

内置功能

Angular 提供了很多开箱即用的功能,例如:

  • 路由:内置导航功能,用来切换页面。
  • 依赖注入(DI):类似 Spring 的依赖注入机制,方便管理服务。
  • 表单验证:支持复杂的表单校验。
适合场景

Angular 适合大型企业级应用,例如:

  • ERP 系统:如进销存、财务管理系统。
  • 复杂的门户网站:需要精细化模块管理的项目。
文件类型

.ts(逻辑):

  • 编写逻辑代码,定义变量、方法和服务。

.html(模板):

  • 定义组件的界面结构。

.css(样式):

  • 设置界面样式,分离逻辑和样式。

二、前端核心文件类型及结构

1. 文件类型

1.1 .html 文件

  • 定义:
    • .html 文件用于定义网页的基本结构,是前端应用的入口文件。
    • 它提供一个“容器”,前端框架(如 Vue、React)会将内容渲染到这个容器中。
  • 作用:
    • 设置页面骨架(如标题、按钮、输入框等)。
    • 为 JavaScript 应用提供挂载点(如 <div id="app">)。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Frontend App</title>
</head>
<body>
  <!-- 前端应用将挂载到这里 -->
  <div id="app"></div>

  <!-- 引入应用主文件 -->
  <script src="./main.js"></script>
</body>
</html>

1.2 .css 文件

  • 定义:
    • .css 文件用于控制网页的样式,例如字体、颜色、布局等。
  • 作用:
    • 为 HTML 元素添加视觉效果。
    • 提高页面的美观性和用户体验。

示例:

/* 全局样式 */
body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
}

/* 按钮样式 */
.button {
  color: white;
  background-color: blue;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
}

1.3 .js 和 .ts 文件

  • 定义: 用于编写页面的逻辑代码,实现动态交互。

  • 区别:

    • .js 文件: 使用动态类型语言 JavaScript,灵活但缺乏类型约束。
    • .ts 文件: 使用 TypeScript,提供强类型支持,适合复杂项目。
  • 作用:

    • 定义页面交互逻辑、事件处理、API 调用等。
    • 类似 Java 中的业务逻辑类,但用于前端。

示例:

// JavaScript 示例
const greet = (name) => `Hello, ${name}`;
console.log(greet('World'));
// TypeScript 示例
const sum = (a: number, b: number): number => a + b;
console.log(sum(5, 10));

1.4 .vue 文件

  • 定义:
    • Vue.js 特有文件类型,整合了 HTML(模板)、CSS(样式)和 JavaScript(逻辑)于一个文件中。
    • 每个 .vue 文件就是一个独立的组件。
  • 作用:
    • 提供单文件组件(SFC, Single File Component),便于开发、维护和模块化。

示例:

<template>
  <!-- HTML 模板 -->
  <div>{{ message }}</div>
</template>

<script>
// JavaScript 逻辑
export default {
  data() {
    return {
      message: 'Hello Vue!'
    };
  }
};
</script>

<style>
/* 样式 */
div {
  color: red;
}
</style>

2. 不同架构对不同类型文件的适配 

文件类型/工具ReactVue.jsAngular是否可混用说明
.html✔️✔️✔️可以混用标准结构文件,作为应用入口,定义挂载点,三种框架均可使用。
.css✔️✔️✔️可以混用标准样式文件,用于全局或模块化样式控制,三种框架均支持直接引入。
.js✔️✔️✔️可以混用标准 JavaScript 文件,存储工具函数、业务逻辑等,与框架无关。
.ts✔️✔️✔️可以混用TypeScript 文件,提供强类型支持,三种框架均支持。
.vue✔️不推荐混用Vue.js 独有的单文件组件,包含模板、样式、逻辑,仅支持 Vue 框架。
.jsx / .tsx✔️不推荐混用React 独有的文件类型,包含 JSX 语法,仅适用于 React。

可以混用的文件类型

  • .html:三种框架都以 .html 作为入口文件,负责挂载根组件。
  • .css:可用于全局或局部样式,三种框架支持一致。
  • .js 和 .ts:作为通用逻辑文件,能在框架之间共享工具代码。

不推荐混用的文件类型

  • .vue:仅限于 Vue 框架,其他框架无法解析。
  • .jsx/.tsx:仅限于 React 框架,其他框架无法解析 JSX 语法。

特殊说明

  • 虽然 .html 文件可以被三种框架使用,但 React 和 Vue 主要将其用作挂载点,而 Angular 会将其用作模板的一部分。

3. 文件夹结构(通用)

一个典型的前端项目的文件夹结构如下:

project/
├── public/                # 静态资源,如图片、HTML 模板
│   ├── favicon.ico        # 网站图标
│   └── index.html         # HTML 模板文件
├── src/                   # 源代码
│   ├── components/        # 可复用的通用组件
│   │   ├── Header.vue     # Vue 项目的头部组件
│   │   ├── Button.jsx     # React 项目的按钮组件
│   │   └── Footer.tsx     # 使用 TypeScript 的底部组件
│   ├── pages/             # 页面级组件
│   │   ├── Home.vue       # Vue 项目的主页
│   │   └── Dashboard.jsx  # React 项目的控制面板
│   ├── styles/            # 全局或模块化的样式文件
│   │   └── main.css       # 全局样式
│   ├── App.vue            # Vue 项目主入口文件
│   ├── App.jsx            # React 项目主入口文件
│   └── main.ts            # 应用的入口逻辑
├── package.json           # 项目的依赖和脚本配置文件
└── vite.config.js         # 构建工具(Vite)的配置文件

解释

public/:

  • 用于存放静态资源,如图片、图标和 HTML 模板。
  • 前端框架通常会将 index.html 作为入口文件,用来加载 JavaScript。

src/:

  • 核心代码目录,所有动态功能都在这里实现。
  • components/:
    • 存放通用组件,例如按钮、表单等,可以在多个页面复用。
  • pages/:
    • 页面级别的组件,每个文件对应一个完整的页面逻辑。
  • styles/:
    • 用于存放全局样式(如主色调定义)或模块化样式文件。
  • App.vue 或 App.jsx

    • 用途: 前端应用的主入口组件,类似于 Spring Boot 的 @SpringBootApplication 类,负责启动和加载核心模块。
  • main.js

    • 用途: 应用的总入口,初始化应用并挂载到 HTML 中的容器。

package.json:

  • 项目配置文件,记录了项目依赖的第三方库和常用脚本命令。
  • 类似于 Java 的 pom.xml 文件。

vite.config.js:

  • 配置前端构建工具(如 Vite),用于定义构建规则、路径别名等。

三、模块化开发

1. 什么是组件

组件是模块化开发的核心。你可以把它看成是一个“功能盒子”,每个组件负责一个小任务,比如显示一个按钮、表单或列表。


1.1.React 中的组件

简单理解:

  • 在 React 里,组件就像 Java 的类,一个组件封装一块功能,比如一个按钮。
  • 组件可以接收外部传来的数据(叫 props),比如按钮的名字。

例子:

// 定义一个按钮组件
const Button = ({ label }) => {
  return <button>{label}</button>; // 渲染一个按钮,显示传进来的文字
};

// 使用按钮组件
const App = () => {
  return (
    <div>
      <Button label="点我一下" /> {/* 使用按钮组件,传递文字 "点我一下" */}
    </div>
  );
};

解释:

  • Button 是一个独立的组件,功能是显示一个按钮。
  • label 是传进来的数据(props),显示在按钮上。
  • 你可以复用这个按钮组件,给它不同的 label,它会显示不同的文字。

1.2.Vue 中的组件

简单理解:

  • Vue 的组件是一个完整的文件(.vue),包括 HTML(界面)、CSS(样式)、JavaScript(逻辑)。

  • 每个 .vue 文件就是一个独立的功能模块。

例子:

<template>
  <!-- 按钮模板 -->
  <button>{{ label }}</button>
</template>

<script>
// 组件逻辑
export default {
  props: ['label'], // 接收外部传来的数据 "label"
};
</script>

<style scoped>
/* 组件样式 */
button {
  background-color: blue;
  color: white;
  padding: 10px 20px;
}
</style>

解释:

  • 这个 .vue 文件是一个独立的组件,定义了一个按钮。
  • props: 接收外部传来的数据(label),比如按钮上的文字。
  • <style scoped>: 样式只作用在这个组件中,不会影响其他地方。

2. 样式和脚本的模块化

2.1 样式模块化

模块化样式是指每个组件的样式只影响自己,互相不会干扰。


React 的 CSS Modules
  • React 用 CSS Modules 把样式绑定到组件,样式名字会自动加密,确保不会和其他样式冲突。

例子:

样式文件Button.module.css):

.button {
  background-color: blue;
  color: white;
  padding: 10px 20px;
}

组件文件Button.jsx):

import styles from './Button.module.css'; // 引入模块化样式

const Button = ({ label }) => {
  return <button className={styles.button}>{label}</button>; // 使用样式
};

export default Button;

解释:

  • Button.module.css 是这个按钮的样式文件。
  • styles.button 确保样式只作用在当前组件的按钮上,不会影响其他地方。

Vue 的 Scoped CSS
  • Vue 用 <style scoped> 让样式只影响当前组件,不会干扰其他地方。

例子:

<template>
  <button>{{ label }}</button>
</template>

<script>
export default {
  props: ['label'],
};
</script>

<style scoped>
button {
  background-color: blue;
  color: white;
  padding: 10px 20px;
}
</style>

解释:

  • 加上 scoped 后,Vue 会自动给样式加上独特的标识符,让样式只作用在这个按钮上。

2.2 脚本模块化

模块化脚本是指把通用的逻辑拆分成独立的文件,哪里需要用就导入,避免重复写代码。


React 和 Vue 的脚本模块化

步骤:

  1. 把通用逻辑写在工具文件里(例如计算函数)。

  2. 在组件中导入工具函数。

例子:

工具文件utils.js):

// 计算两个数字的和
export const calculateSum = (a, b) => a + b;

React 组件:

import { calculateSum } from './utils';

const App = () => {
  const result = calculateSum(5, 10); // 使用工具函数
  return <div>Sum: {result}</div>;
};

export default App;

Vue 组件:

<template>
  <div>Sum: {{ result }}</div>
</template>

<script>
import { calculateSum } from './utils';

export default {
  data() {
    return {
      result: calculateSum(5, 10), // 使用工具函数
    };
  },
};
</script>

解释:

  • utils.js 是一个通用的工具文件,定义了 calculateSum 函数。
  • React 和 Vue 的组件都可以导入这个函数,直接使用,避免重复写逻辑。

总结

内容ReactVue
组件用函数或类封装,类似 Java 类。使用 .vue 文件,封装界面、逻辑和样式。
样式模块化使用 CSS Modules 隔离样式。使用 <style scoped> 隔离样式。
脚本模块化使用工具文件(如 utils.js)按需导入。使用工具文件或 Mixins 按需导入。

四、前端构建工具

1. 为什么需要构建工具

在开发过程中,前端代码往往包含最新的技术(如 ES6、TypeScript、模块化开发)和特定框架的文件格式(如 .vue)。然而,浏览器无法直接运行这些文件或代码,需要一个“中间工具”来完成以下任务:

(1)转换代码:

  • 将现代 JavaScript(如箭头函数、模块化)转换为兼容性更好的代码,确保在老旧浏览器中运行。

例如,把以下 ES6 代码:

const sum = (a, b) => a + b;

转换为浏览器支持的 ES5 代码:

var sum = function (a, b) {
  return a + b;
};

(2)优化代码:

  • 压缩 JavaScript 和 CSS 文件,减少文件大小。
  • 合并文件,减少浏览器加载的请求次数。

(3)模块化支持:

  • 开发时,我们将代码拆分为多个模块(如组件和工具文件),构建工具可以将它们合并为一个文件供浏览器使用。

(4)开发体验:

  • 提供一个本地开发服务器,支持热更新(HMR),修改代码后,浏览器会立即更新,无需手动刷新。

2. 构建项目的过程

在使用构建工具(如 Vite 或 Webpack)创建项目时,通常会用到以下两步:

安装依赖

  • 使用 npm install 安装项目所需的依赖库。
  • 依赖库包含构建工具(如 Vite 或 Webpack)、框架(如 React 或 Vue)及其他工具。

启动开发环境

  • 使用 npm run dev 启动本地开发服务器。
  • 开发服务器会运行项目代码,支持实时热更新,让你在浏览器中实时看到修改效果。

2.1 npm install 的作用

  • npm install 会根据 package.json 文件中定义的依赖,下载所需的库,并存储在项目的 node_modules 文件夹中。
  • package.json 示例:
{
  "dependencies": {
    "vue": "^3.0.0"
  },
  "devDependencies": {
    "vite": "^2.0.0"
  }
}
  • 命令解释:
    • dependencies: 项目运行时所需的库(如框架 vue)。
    • devDependencies: 仅开发阶段需要的工具(如构建工具 vite)。

2.2 npm run dev 的作用

  • npm run dev 会执行 package.json 文件中定义的脚本,用于启动开发环境。
  • 脚本配置:
{
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  }
}
  • 命令解释:
    • npm run dev: 运行 vite,启动本地开发服务器。
    • 效果:
      • 项目会在本地启动一个服务器(如 http://localhost:3000)。
      • 浏览器自动打开页面,实时展示开发效果。

3. Vite

3.1 什么是 Vite

  • Vite 是一种轻量、快速的前端构建工具,专为现代框架(如 Vue 和 React)设计。
  • 它的最大特点是速度快,适合中小型项目。

3.2 功能

  • 极速启动:

    • 使用浏览器原生的模块化支持(ES Modules),跳过传统的打包步骤,直接加载需要的代码。
  • 热模块替换(HMR):

    • 修改代码后,浏览器会自动更新页面,无需手动刷新。
  • 生产环境优化:

    • 在打包时,会压缩代码、分割模块、删除无用代码,提升加载性能。

3.3 构建项目(以 Vue 为例)

1. 初始化项目
# 创建一个新项目
npm create vite@latest my-vite-app
# 进入项目文件夹
cd my-vite-app
# 安装项目依赖
npm install
2. 启动开发环境
npm run dev

运行后:

  • Vite 启动一个本地开发服务器(默认端口是 5173)。
  • 浏览器打开项目后,修改代码会自动刷新页面。
3. 打包生产环境
npm run build

作用:

  • 将开发中的代码打包成优化后的静态文件(HTML、CSS、JavaScript)。
  • 生成的文件会存放在 dist/ 目录中。
4. 示例 Vite 项目结构
my-vite-app/
├── public/          # 静态资源(如图片)
├── src/             # 项目源码
│   ├── App.vue      # Vue 主组件
│   ├── main.js      # 应用入口
├── package.json     # 项目配置文件
└── vite.config.js   # Vite 配置文件

4. Webpack

4.1 什么是 Webpack

  • Webpack 是功能强大的构建工具,适合大型项目。它可以将多个文件(如 JavaScript、CSS、图片)打包成优化的静态文件。

4.2 功能

  • 文件打包:

    • 将模块化开发的多个文件合并为一个或多个静态文件供浏览器加载。
  • 代码分割:

    • 按需加载代码。例如,用户访问登录页面时只加载登录相关的文件。
  • 丰富的插件支持:

    • 提供插件和加载器支持各种文件的处理(如 Babel 转换 JavaScript,PostCSS 处理样式)。

4.3 构建项目

1. 初始化项目
# 创建一个新项目文件夹
mkdir my-webpack-app
cd my-webpack-app
# 初始化 package.json 文件
npm init -y
# 安装 Webpack 和 CLI 工具
npm install webpack webpack-cli --save-dev
2. 配置 Webpack

在项目根目录创建 webpack.config.js 文件:

const path = require('path');

module.exports = {
  entry: './src/index.js', // 项目入口文件
  output: {
    path: path.resolve(__dirname, 'dist'), // 打包输出目录
    filename: 'bundle.js', // 输出的文件名
  },
  module: {
    rules: [
      {
        test: /\.css$/, // 处理 CSS 文件
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};
3. 创建源码

目录结构:

my-webpack-app/
├── src/
│   ├── index.js     # 主入口文件
│   └── styles.css   # 样式文件
├── webpack.config.js # 配置文件
├── package.json      # 项目配置
4. 启动开发环境
npx webpack serve

运行后:

  • Webpack 启动开发服务器,监视文件变化,实时更新页面。
5. 打包生产环境
npx webpack --mode production

作用:

  • 将代码打包为优化后的静态资源,适合部署到服务器。

5. Vite 和 Webpack 的对比

特性ViteWebpack
启动速度非常快(直接使用浏览器模块支持)较慢(需要先打包文件)
配置难度简单,开箱即用复杂,可高度自定义
代码分割和优化默认支持需要手动配置
适合场景中小型项目、快速开发大型项目、复杂需求


五、CSS 框架

1. Bootstrap

1.1 什么是 Bootstrap

Bootstrap 是一个流行的 CSS 框架,提供了丰富的预定义样式和组件,例如按钮、表单、导航栏等。它简化了前端开发流程,特别适合快速构建通用 UI。

1.2 Bootstrap 的特点

(1)预定义组件
Bootstrap 提供了许多现成的 UI 组件,直接通过类名使用即可。例如,按钮、表单、模态框(弹窗)等组件。
示例:

<button class="btn btn-primary">提交</button>
  • btn 是按钮的基本样式,btn-primary 添加了蓝色背景样式。

(2)响应式布局
Bootstrap 的网格系统可以帮助你轻松实现自适应布局。通过简单的类名,就可以让页面在手机、平板和桌面设备上都保持良好的显示效果。
示例:

<div class="row">
  <div class="col-md-6">左侧内容</div>
  <div class="col-md-6">右侧内容</div>
</div>
  • row 定义一行,col-md-6 定义列宽占 12 格中的 6 格(即一半宽度)。

(3)快速开发
通过内置样式,开发者可以专注于功能开发而非手写样式代码。例如,导航栏、表单、按钮等都可以直接使用预定义样式。

1.3 Bootstrap 的适用场景

  • 快速开发:当项目对个性化设计要求不高时,Bootstrap 是一个极好的选择,比如后台管理系统、公司官网等。
  • 一致性设计:需要统一的设计风格时,Bootstrap 提供了完整的设计规范,适合团队协作。

2. Tailwind CSS

2.1 什么是 Tailwind CSS

Tailwind CSS 是一种实用优先的 CSS 框架,它通过类名直接定义样式,开发者可以灵活组合这些类来实现高度自定义的设计风格。相比 Bootstrap 提供现成组件,Tailwind 更加注重自由和灵活性。

2.2 Tailwind CSS 的特点

(1)按类名定义样式
在 Tailwind 中,每个类名都对应一个特定的样式,你可以通过组合这些类名来创建自己的设计。
示例:

<button class="bg-blue-500 text-white px-4 py-2 rounded">
  提交
</button>
  • bg-blue-500 设置背景颜色为蓝色,text-white 设置文字颜色为白色,px-4 和 py-2 分别设置左右和上下的内边距,rounded 设置按钮圆角。

(2)高度可定制
Tailwind 支持通过配置文件(tailwind.config.js)进行样式定制,你可以修改默认的颜色、间距等样式规则。
示例:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        customBlue: '#1DA1F2', // 添加一个自定义蓝色
      },
    },
  },
};

(3)无全局污染
Tailwind 的类名独立存在,不会影响全局样式,也不会与其他框架冲突。每个类名仅作用于你指定的地方。

2.3 Tailwind CSS 的适用场景

  • 个性化设计:当项目需要独特的风格和完全自定义的设计时,Tailwind 是一个非常灵活的选择,比如品牌官网、个人作品集等。
  • 精细控制:如果你希望完全掌控页面样式,而不是使用框架的现成组件,Tailwind 非常适合。

3. 对比 Bootstrap 和 Tailwind CSS

特性BootstrapTailwind CSS
使用方式提供现成的组件(如按钮、表单、导航栏)通过类名组合直接定义样式
灵活性固定组件,灵活性有限高度灵活,可以完全自定义
学习难度上手简单,只需了解基本组件需要记住大量类名,初学者可能稍难
适用场景快速开发通用 UI 项目需要高度定制的项目
设计风格统一、规范自由、个性化

六、前后端分离与通信

前后端分离模式:

  • 前端:
    • 专注于页面的展示和交互,使用现代前端框架(如 React、Vue)构建页面。
    • 通过调用后端提供的接口(API)获取数据。
  • 后端:
    • 专注于业务逻辑和数据处理,提供标准化的数据接口(REST API)。
    • 数据以 JSON 格式返回,前端接收到后进行解析并展示。

1. 使用 axios 调用后端 API

1.1 什么是 axios

  • 定义axios 是一个基于 Promise 的 HTTP 客户端库,专为浏览器和 Node.js 设计。
  • 特点:
    • 简单易用。
    • 支持各种 HTTP 请求方法(GET、POST、PUT、DELETE 等)。
    • 支持请求和响应拦截器,便于统一处理逻辑。

1.2 安装 axios

npm install axios

1.3 调用 API 示例:GET 请求

代码实现

import axios from 'axios';

axios.get('/api/resource') // 调用后端 API,获取数据
  .then(response => {
    // 成功时的回调
    console.log('后端返回的数据:', response.data);
  })
  .catch(error => {
    // 错误处理
    console.error('请求失败:', error);
  });

逻辑解析

GET 请求:

  • 目标: 向后端获取数据。
  • 请求方式: axios.get(url)url 是 API 的地址。
  • response.data 包含后端返回的数据(通常是 JSON 格式)。

axios.get('/api/resource'):

  • 向后端发送一个 GET 请求,目标是 /api/resource
  • GET 请求常用于查询数据,不携带请求体。

.then(response => { ... }):

  • 当后端成功返回数据时,进入 then 回调。

response.data:

  • 包含后端返回的核心数据(通常是 JSON 格式)。

.catch(error => { ... }):

  • 如果请求失败(如网络错误或服务器错误),进入 catch 回调。
  • 可以在此处理错误,比如显示友好的错误提示。

1.4 调用 API 示例:POST 请求

代码实现

import axios from 'axios';

axios.post('/api/resource', { name: 'example' }) // 向后端提交数据
  .then(response => {
    // 成功时的回调
    console.log('后端返回的数据:', response.data);
  })
  .catch(error => {
    // 错误处理
    console.error('请求失败:', error);
  });

逻辑解析

POST 请求:

  • 目标: 向后端提交数据。
  • 请求方式: axios.post(url, data),其中 data 是提交的数据对象(会转换为 JSON)。
  • 响应数据: response.data 包含后端返回的处理结果。

axios.post('/api/resource', { name: 'example' }):

  • 发送一个 POST 请求,目标是 /api/resource
  • 第二个参数 { name: 'example' } 是请求体,通常为 JSON 格式。
  • POST 请求用于提交数据到服务器。

response.data:

  • 包含后端返回的处理结果。例如:
    后端返回 { "status": "success", "data": { "id": 1, "name": "example" } }

错误处理:

  • 通过 catch 捕获错误,比如请求失败或服务器返回 500 错误。

2. 使用 fetch 调用后端 API

2.1 什么是 fetch

  • 定义fetch 是浏览器内置的 HTTP 请求 API,基于 Promise。
  • 特点:
    • 不需要安装,浏览器原生支持。
    • 功能强大,但语法比 axios 稍显繁琐。

2.2 调用 API 示例:GET 请求

代码实现

fetch('/api/resource') // 调用后端 API,获取数据
  .then(response => {
    if (!response.ok) {
      throw new Error('网络响应失败'); // 检查响应状态
    }
    return response.json(); // 将响应数据转换为 JSON
  })
  .then(data => {
    console.log('后端返回的数据:', data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

逻辑解析

GET 请求:

  • 目标: 向后端获取数据。
  • 响应处理: response.json() 将返回的 JSON 数据解析为 JavaScript 对象。
  • 错误处理: 如果 response.ok 为 false,需要手动抛出错误。

fetch('/api/resource'):

  • 发送一个 GET 请求,目标是 /api/resource

.then(response => { ... }):

  • response 包含 HTTP 响应的元信息(如状态码、响应头等)。

response.ok:

  • 如果状态码为 200-299,ok 为 true;否则为 false

response.json():

  • 将响应体转换为 JSON 数据,返回一个 Promise。

.then(data => { ... }):

  • 接收到的 data 就是后端返回的数据内容。

2.3 调用 API 示例:POST 请求

代码实现

fetch('/api/resource') // 调用后端 API,获取数据
  .then(response => {
    if (!response.ok) {
      throw new Error('网络响应失败'); // 检查响应状态
    }
    return response.json(); // 将响应数据转换为 JSON
  })
  .then(data => {
    console.log('后端返回的数据:', data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

逻辑解析

POST 请求:

  • 目标: 向后端提交数据。
  • 设置请求头: 使用 headers 声明 Content-Type 为 application/json
  • 设置请求体: 使用 body 提交数据,需先用 JSON.stringify 转换为 JSON 字符串。
  • 响应处理: 同样通过 response.json() 解析返回数据。

method: 'POST':

  • 指定请求方法为 POST,用于提交数据。

headers:

  • 设置请求头,声明数据格式为 application/json

body: JSON.stringify({...}):

  • 提交的数据需要先转换为 JSON 字符串。

3. 前端如何接收后端返回的数据并绑定到页面

3.1 Vue 示例

完整代码

<template>
  <div>
    <p>用户 ID: {{ resource.id }}</p>
    <p>用户名称: {{ resource.name }}</p>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      resource: {}, // 用于存储后端返回的数据
    };
  },
  created() {
    // 调用后端 API
    axios.get('/api/resource').then(response => {
      this.resource = response.data; // 将返回数据绑定到组件
    });
  },
};
</script>

逻辑解析

data 定义数据对象:

  • resource 用于存储后端返回的数据。

created 生命周期:

  • 组件加载时调用 API。
  • 将返回的数据赋值给 resource

数据绑定:

  • {{ resource.id }} 和 {{ resource.name }} 会动态展示数据。

3.2 React 示例

完整代码

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const App = () => {
  const [resource, setResource] = useState({}); // 定义状态

  useEffect(() => {
    // 调用后端 API
    axios.get('/api/resource').then(response => {
      setResource(response.data); // 设置状态
    });
  }, []);

  return (
    <div>
      <p>用户 ID: {resource.id}</p>
      <p>用户名称: {resource.name}</p>
    </div>
  );
};

export default App;

逻辑解析

状态管理:

  • 使用 useState 定义 resource 状态,用于存储数据。

useEffect 调用 API:

  • 组件挂载时(类似 Vue 的 created),调用后端 API。

数据展示:

  • 通过 {resource.id} 和 {resource.name} 将数据动态渲染到页面。

4.前端调用后端API时请求体为JSON格式

前端调用后端的API时,传递的参数一般包含在请求体中,而请求体一般为JSON格式(可以在请求头中通过修改Content-Type属性来换成其他格式,但一般创建Axios实例时指定为JSON格式)。

(1)请求格式为什么是 JSON?

默认配置为 JSON 格式 在 api(即 Axios 实例)的创建中指定了 Content-Type: application/json

const api = axios.create({
    baseURL: API_BASE_URL,
    timeout: 10000,
    headers: {
        'Content-Type': 'application/json', // 默认请求头
    },
});
  • 这段配置明确告诉 Axios,发送请求时的默认格式是 JSON。

(2)通过Axios发送请求示例

以下前端使用 Axios 发送 HTTP 请求的一段代码,目的是向后端 /auth/login 接口发送登录请求。

login: (username: string, password: string) =>
    api.post('/auth/login', { username, password }),

login 函数的定义

  • login 是一个箭头函数,接收两个参数:
    • username:类型是字符串,表示用户名。
    • password:类型是字符串,表示密码。
  • 函数返回一个 Promise,代表向后端发起的异步请求。

api.post 方法

  • api 是通过 axios.create 创建的 Axios 实例,用于发送 HTTP 请求。
  • post 是 Axios 提供的 HTTP POST 请求方法,格式为:
    api.post(url, data, config?)
    
    • url: 请求路径,这里是 '/auth/login'
    • data: POST 请求体内容,这里是 { username, password }
    • config?: 可选参数,用于配置请求的额外属性(如请求头、超时时间等)。

请求体 { username, password }

  • { username, password } 是一个对象,表示将两个字段 username 和 password 作为请求体发送给后端。
  • Axios 会根据请求头中的 Content-Type 自动将这个对象序列化为 JSON 字符串。

 (3)通过其他格式的请求体向后端发送请求(修改请求头中的Content-Type属性)

文件上传(multipart/form-data

文件上传时,使用 multipart/form-data 格式发送数据:

const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
formData.append('file', file); // 文件数据

api.post('/auth/upload', formData, {
    headers: { 'Content-Type': 'multipart/form-data' },
});

请求体示例:

Content-Disposition: form-data; name="username"
yourUsername
Content-Disposition: form-data; name="file"; filename="example.jpg"
<binary data>

常见场景:

  • 上传图片、视频等文件。

查询参数(GET 请求或 URL 参数)

某些接口直接通过 URL 查询参数传递数据:

api.get('/auth/login', { params: { username, password } });

Axios 会将参数序列化为查询字符串:

/auth/login?username=yourUsername&password=yourPassword

常见场景:

  • 无需敏感信息的简单查询请求。
场景/需求推荐请求格式理由
查询公开数据查询参数(GET)URL 参数直观,不涉及敏感信息,利于调试和缓存。
无状态的简单筛选、分页、排序查询参数(GET)符合 RESTful 风格,适合简单的只读操作。
包含敏感信息(如密码、token)JSON 格式(POST)数据在请求体中,不暴露在 URL,更安全。
数据结构复杂(如对象嵌套、数组)JSON 格式(POST)查询参数表达能力不足,JSON 格式更灵活。
数据量大(如文件、长字符串)JSON 格式(POST)URL 长度有限,JSON 格式可以承载更大的数据量。
需要搜索引擎索引查询参数(GET)GET 请求可被索引,适合用于对外展示的接口(如搜索、分类)。
创建、修改、删除资源JSON 格式(POST/PUT/DELETE)JSON 格式更符合 RESTful 语义,适合复杂的数据操作。

 5.前端 Axios 和后端 Spring MVC 的交互流程

5.1. 前端通过 Axios 发起请求

Axios 是一个基于 Promise 的 HTTP 客户端,用于在前端发起 HTTP 请求(如 GET、POST 请求)。它可以用于发送请求并处理响应。前端通过 Axios 与后端的交互通常包括以下几个步骤:

GET 请求:用于获取数据,通常通过 URL 查询参数传递数据(请求参数在URL中)

axios.get('/user', { params: { id: 1, name: 'John' } })
    .then(response => {
        console.log('请求成功:', response.data);
    })
    .catch(error => {
        console.error('请求失败:', error.response.status);
    });
  • 请求 URL 会被拼接成 /user?id=1&name=John
  • 参数通过 params 选项传递,Axios 会自动将它们转换为查询字符串。

POST 请求:用于提交数据,通常通过请求体(body)传递数据。

axios.post('/user', { name: 'John', age: 30 })
    .then(response => {
        console.log('请求成功:', response.data);
    })
    .catch(error => {
        console.error('请求失败:', error.response.status);
    });
  • 请求数据通过 data 选项传递,Axios 会自动将其转化为 JSON 格式。
  • 服务器会接收该数据并执行相应的操作,如保存到数据库等。

Promise 的状态:

  • Resolved(请求成功):当服务器返回的 HTTP 状态码在 2xx 范围内时,Axios 会将 Promise 置为成功状态(resolved)。调用 .then() 回调函数。
  • Rejected(请求失败):当 HTTP 状态码在 4xx 或 5xx 范围内,或发生网络错误时,Axios 会将 Promise 置为失败状态(rejected)。调用 .catch() 回调函数。

响应结构: 当请求成功时,Axios 返回的 response 对象包含以下主要字段:

response = {
    data: {},            // 服务器返回的主要数据(对应 ResponseEntity 的 body)
    status: 200,         // HTTP 状态码(对应 ResponseEntity 的 statusCode)
    statusText: "OK",    // 状态文本(由 HTTP 标准定义,和 ResponseEntity 的 statusCode 含义一致)
    headers: {},         // 服务器返回的 HTTP 响应头(对应 ResponseEntity 中自定义的 headers)
    config: {},          // Axios 请求时的配置信息(与 ResponseEntity 无直接关系)
    request: {}          // 原始请求对象(与 ResponseEntity 无直接关系)
};

当请求失败时,error 对象包含:

error = {
    message: "Request failed with status code 404",  // 错误描述信息
    response: {                                      // 错误响应,包含与成功响应相似的结构
        data: {},                                    // 错误详情(对应 ResponseEntity 的 body)
        status: 404,                                 // HTTP 状态码(对应 ResponseEntity 的 statusCode)
        statusText: "Not Found",                    // 状态文本(与 ResponseEntity 的 statusCode 含义一致)
        headers: {}                                  // 错误响应头(对应 ResponseEntity 中自定义的 headers)
    },
    config: {},                                      // 请求时的配置信息
    request: {}                                      // 原始请求对象
};

5.2. 后端通过 Spring MVC 处理请求

后端使用 Spring MVC(通常通过 @RestController 注解)来处理前端发来的请求。Spring MVC 的工作流程大致如下:

GET 请求:Spring MVC 控制器中的方法会通过 @RequestParam 注解来接收查询参数。

@GetMapping("/user")
public ResponseEntity<User> getUser(@RequestParam Long id, @RequestParam String name) {
    User user = userService.findUser(id, name);
    return ResponseEntity.ok(user);  // 返回响应
}

POST 请求:Spring MVC 使用 @RequestBody 注解来接收请求体(如 JSON 格式的数据),并通过 @RequestBody 将其自动转换为 Java 对象。

@PostMapping("/user")
public ResponseEntity<User> createUser(@RequestBody User user) {
    User createdUser = userService.createUser(user);
    return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);  // 返回响应
}

生成响应

Spring MVC 会根据请求返回适当的响应:

返回复杂相应的话最好就是使用ResponseEntity,因为可以通过ResponseEntity设置状态码以及自定义响应头和响应体,并且也更符合现代API开发规范。

  • 默认返回对象:如果方法返回一个对象,Spring 会使用 Jackson 或类似的 JSON 序列化工具将其自动转换为 JSON 格式,并返回给前端。
  • 自定义响应:如果需要控制响应状态码、头部信息等,可以使用 ResponseEntity
    ResponseEntity<User> responseEntity = ResponseEntity
        .status(HttpStatus.CREATED)
        .header("Custom-Header", "value")
        .body(createdUser);
    
  • 直接返回字符串:如果需要返回一个字符串,Spring 会自动将其作为响应体返回。

ResponseEntity 的结构

  • body:响应的实际数据(如 JSON 对象)。
  • statusCode:HTTP 状态码(如 200、201、404 等)。
  • headers:响应头信息(如内容类型、认证信息等)。

下面是完整的 Promise 对象结构,以及它与 Spring MVC 的 ResponseEntity 的对应关系。


Promise 和 ResponseEntity 的对应关系

Promise 属性ResponseEntity 部分说明
response.dataResponseEntity.body包含服务器返回的主要数据,是响应体部分(如 JSON 格式对象)。
response.statusResponseEntity.statusCodeHTTP 状态码,表示请求结果的状态(如 200 表示成功,404 表示未找到资源)。
response.statusTextResponseEntity.statusCode 语义一致状态码的描述文本(由 HTTP 标准定义,如 200 OK404 Not Found)。
response.headersResponseEntity.headersHTTP 响应头,可能包含缓存控制、认证信息、自定义头部等。
response.config-Axios 请求的配置信息,与 ResponseEntity 无直接对应,包含请求方法、URL、头部等。
response.request-原始请求对象,包含与 ResponseEntity 无关的 Axios 内部信息。
error.response.dataResponseEntity.body错误响应体,包含错误的详细描述信息(如错误代码、错误消息)。
error.response.statusResponseEntity.statusCode错误响应状态码,用于指示错误类型(如 400 表示请求错误,500 表示服务器错误)。
error.response.headersResponseEntity.headers错误响应的头部信息,可能包含调试信息或认证失败原因等。
error.messageResponseEntity 无直接对应Axios 提供的错误描述信息,通常是 Request failed with status code XXX 的形式。

5.3. 如何处理 Axios 的返回值

使用 .then 处理返回值

then 方法用于处理 Promise 成功的情况。当请求成功时,response 对象将作为参数传递给 .then 的回调函数。此时,你可以根据 response.data 获取服务器返回的数据、检查 response.status 获取 HTTP 状态码,或者查看其他字段如 response.headers 来分析响应的元数据。

示例:

axios.get('/user', { params: { id: 1 } })
    .then(response => {
        console.log('请求成功:', response.data); // 输出用户数据
        console.log('状态码:', response.status); // 输出状态码
        console.log('响应头:', response.headers); // 输出响应头
    })
    .catch(error => {
        console.error('请求失败:', error.response.status); // 错误状态码
        console.error('错误信息:', error.message); // 错误描述信息
    });
  • response.data:服务器返回的主要数据,通常是 JSON 格式的对象。
  • response.status:HTTP 状态码,如 200 表示成功,404 表示未找到资源。
  • response.headers:响应头信息,可能包括缓存控制、认证信息等。
使用 async/await 处理返回值

使用 async/await 是更现代的写法,它可以使异步代码更简洁,便于理解。通过 await 等待 Axios 请求返回的 Promise 结果,然后你可以在 try/catch 语句中处理请求成功和失败的情况。

这种方式更常用,如果使用这种方式,就必须要使用  try/catch 语句。

示例:

async function fetchUser() {
    try {
        const response = await axios.get('/user', { params: { id: 1 } });
        console.log('用户信息:', response.data); // 成功获取数据
    } catch (error) {
        console.error('请求失败:', error.response.status); // 错误处理
        console.error('错误信息:', error.message);
    }
}

fetchUser();
  • await axios.get(...):等待 axios.get() 返回的 Promise 完成。
  • try/catch:处理请求成功和失败的两种情况,catch 中的 error 对象包含失败的信息。

当请求失败时,返回的error 对象包含错误的详细信息。通过 error.response 获取服务器返回的错误信息(如 404 错误的详细描述),通过 error.message 获取网络层面的错误描述(如请求超时等)。 

5.4 前后端交互总结

步骤前端(Axios)后端(Spring MVC)
请求发起通过 axios.getaxios.post 发起 HTTP 请求,携带 URL 参数或请求体Spring MVC 控制器方法通过注解(如 @GetMapping@PostMapping)处理请求
请求内容GET:通过 params 传递查询参数;POST:通过请求体(JSON)传递数据通过 @RequestParam(GET)或 @RequestBody(POST)接收数据
响应处理Promise 返回,通过 thencatch 处理响应数据和错误信息返回对象(自动序列化为 JSON),或通过 ResponseEntity 控制状态码和头部
响应内容response.data:服务器返回的数据,response.status:HTTP 状态码返回对象通过 Jackson 自动转换为 JSON 格式,状态码通过 ResponseEntity 自定义
状态码和头部信息通过 response.statusresponse.headers 获取状态码和响应头通过 ResponseEntity 设置状态码(如 200、404)和自定义响应头
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值