了解前端框架

实际上,我在学习了很长一段时间的后端之后才接触到前端框架,所以说,这是一个比较尴尬的事情

后端的框架我们都比较熟悉,主要内容其实无非就是用于处理处理业务逻辑和数据持久化

后端框架是面向服务设计的,它更关注数据的正确性和安全性,倾向于实际业务的逻辑和数据

而且后端框架一般都会有很多的关于多线程并发处理的内容,因为这会提升性能

而 Vue 这种前端框架,它是处理用户交互和数据展示的,主要是用户与业务的交互

Vue 是面向组件设计的,这是前端框架设计模式的一种,而且它着重关注用户体验和界面流畅性

一般情况下,Vue 是单线程,异步处理的,因为 JavaScript 语言本身就是单线程的。这主要源于浏览器的设计

你想想,操作 DOM 不仅是单线程,而且是有严格的前后步骤的,如果允许多线程同时操作 DOM,会导致渲染冲突和不可预测的结果,JavaScript 最初设计就是为了处理页面交互,单线程模型足够满足需求且实现简单

多线程需要处理线程同步、锁机制等复杂问题,这纯粹是给前端开发没事找事

前后端框架关系

后端的大伙去学习前端框架的时候,都会因为 开发模式 变了,而感觉眩晕))

而不是代码本身有多难

我觉得 JS 再阴间也没 Java 的那些动态代理,反射折磨人

传统的 JSP/Thymeleaf 模式,到现代的前后端分离模式,说明一下前后端框架关系

我们进行JSP / Thymeleaf进行开发的时候,整个的流程大伙比较熟悉

浏览器请求 URL -> Spring Controller -> Service/DAO -> **后端把数据填进 HTML 模板** -> **后端把渲染好的完整 HTML 返回给浏览器**。

页面长什么样,完全由 Java 代码控制。

前端只是写写 CSS 和静态 HTML,后端负责逻辑和页面组装。

这样很难绷,因为页面一刷新就是重新加载,手机 App 要用数据时,后端还得重写一套接口

Vue + Spring Boot 这种比较常见的前后端分离是这样的,后端是仓库管理员,前端是装修工,考虑这样一个流程

  1. 浏览器打开网页,首先加载的是 Vue 的空壳代码(前端静态资源)。
  2. Vue 代码在浏览器运行,发现需要数据,于是发起 HTTP 请求(Ajax/Axios)。
  3. Java 后端(Spring Boot)只负责查询数据,返回 JSON(不包含任何 HTML 标签)。
  4. Vue 拿到 JSON,在浏览器里把数据填进页面,生成用户看到的界面。

Java 不再生成 HTML,只吐 JSON 数据。

那么,作为后端高手的大伙,估计就都知道我们最关心的事情了,数据怎么传

在 Vue 中,我们通常使用一个叫 Axios 的库,它是 Ajax 的升级版,类似 Java 里的 RestTemplateHttpClient

它是发请求的

用户列表查询为例子

  1. Java 后端 (Spring Boot):

    • 提供接口: @GetMapping("/api/users")
    • 返回: [{"id":1, "name":"Admin"}, {"id":2, "name":"User"}] (JSON)
  2. Vue 前端:

    • mounted()(相当于初始化方法) 里调用接口。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      <script>
      import axios from 'axios'; // 引入 HTTP 工具

      export default {
      data() {
      return {
      userList: [] // 初始为空列表
      }
      },
      // 页面加载完,自动执行这个方法(类似 Java 的 @PostConstruct)
      mounted() {
      this.loadData();
      },
      methods: {
      loadData() {
      // 发送 GET 请求给 Spring Boot
      axios.get('/api/users')
      .then(response => {
      // 拿到后端返回的 JSON,赋值给 data
      // 此时页面会自动刷新,渲染出列表
      this.userList = response.data;
      })
      .catch(error => {
      console.error("接口挂了", error);
      });
      }
      }
      }
      </script>

怎么前端现在的开发环境跟后端越来越像了:

  1. Node.js ≈≈ JDK
    • 运行 JS 的环境,就像运行 Java 需要 JDK。
  2. npm (或 yarn/pnpm) ≈≈Maven / Gradle
    • npm install axios 就等于在 pom.xml 里加依赖。
    • package.json 就等于 pom.xml
  3. Vue CLI / Vite ≈≈Spring Initializr
    • 帮你快速生成一个项目脚手架,搭建好目录结构。
  4. Webpack / Vite ≈≈ Compiler + Maven Build
    • 把 Vue 代码编译、打包、压缩成浏览器能跑的 .js 和 .html 文件。
  5. Nginx ≈≈Tomcat (生产环境)
    • 前端打包完是一堆静态文件,通常放在 Nginx 上跑,而不是放在 Tomcat 里。

实际上,前端封装好的东西更多,我们一开始学习 CSS 那都不得不品的一环就是 画圆

这东西自己写的越少越好,让 UI 做或者用现成的组件库

学习 Vue 关注的应该是

  1. 基础语法:了解 v-if (就像 JSP 的 ), v-for (就像 ), v-model (表单绑定)。
  2. 生命周期:重点理解 mounted,知道去哪里发请求。
  3. 组件通信
    • 父传子 (Props) ≈≈ 方法传参。
    • 子传父 (Events) ≈≈ 回调函数/观察者模式。
  4. 组件库(神器)
    • 千万不要自己写 CSS!
    • 去学 Element UI (Element Plus)Ant Design Vue
    • 它们就像后端常用的 Hutool 或 Apache Commons,给你提供了现成的 按钮、表格、弹窗,拿来就用。

最后总结一下,Vue 就是运行在浏览器里的一个简易 Spring 容器。

  • 它管理对象(data)。
  • 它管理视图(template)。
  • 它通过 HTTP (Axios) 和你的 Spring Boot 交换 JSON 数据。

数据驱动视图

数据驱动视图

数据驱动视图

了解 Vue

Vue.js 是由尤雨溪(Evan You)创建的前端 JavaScript 框架,主要用于构建单页应用(SPA)和复杂的用户界面。Vue.js 提供了响应式的数据绑定和组合的视图组件功能。

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式 JavaScript 框架。与其他大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

这是什么意思

渐进式” 意味着 Vue 的功能可以按需使用,你不必一开始就掌握和使用它的所有特性。你可以根据项目需求,逐步引入更多功能,而不是一次性全盘接受。你可以只拿一块积木(Vue 核心库)来做简单的页面,也可以根据需要,添加路由积木、状态管理积木、构建工具积木等

自底向上逐层应用就是字面意思, Vue 允许你从最基础的层面开始使用,然后根据项目复杂度的提升,逐层添加更高级的功能。一般顺序就是引入->页面->组件->路由->状态管理->完整工程

用多少,学多少,学多少,用多少。

Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue 支持声明式的渲染,这是Vue 的核心功能之一,让你只需要描述数据和视图的映射关系,而不用手动操作 DOM。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- HTML -->
<div id="app">
<h1>{{ message }}</h1>
<p>{{ user.name }} - {{ user.age }}岁</p>
</div>

<script>
// JavaScript
new Vue({
el: '#app', // 挂载点,对应HTML中的id="app"
data: { // 数据对象
message: 'Hello Vue!',
user: {
name: '张三',
age: 25
}
}
})
</script>

这就是MVVM 模式的体现:数据 (data) 变化会自动更新视图 (View),无需手动操作

Vue 主要操作是指令,它是 Vue 提供的特殊 HTML 属性,以v-开头,用于在 DOM 上应用特殊行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div id="app">
<!-- 条件渲染 -->
<p v-if="isShow">这是条件显示的内容</p>

<!-- 列表渲染 -->
<ul>
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>

<!-- 事件绑定 -->
<button v-on:click="handleClick">点击我</button>
<!-- 简写 -->
<button @click="handleClick">点击我</button>

<!-- 属性绑定 -->
<img v-bind:src="imageUrl" alt="示例图片">
<!-- 简写 -->
<img :src="imageUrl" alt="示例图片">

<!-- 双向数据绑定 -->
<input v-model="inputValue" placeholder="输入内容">
<p>你输入的是:{{ inputValue }}</p>
</div>

Vue 是组件化思想,将页面拆分为可复用的独立单元。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 定义全局组件
Vue.component('my-component', {
props: ['title'], // 接收父组件传递的属性
template: `
<div class="component">
<h3>{{ title }}</h3>
<p>这是一个可复用的组件</p>
</div>
`
})

// 在Vue实例中使用
new Vue({
el: '#app'
})
1
2
3
4
5
<!-- 使用组件 -->
<div id="app">
<my-component title="组件标题1"></my-component>
<my-component title="组件标题2"></my-component>
</div>

和 Spring Boot 类似,Vue 实例从创建到销毁的过程中,会触发一系列钩子函数,允许你在特定阶段执行代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
new Vue({
el: '#app',
data: {
message: 'Hello'
},
// 常用生命周期钩子
created() {
console.log('实例已创建,数据已初始化')
// 可以在这里发起数据请求
},
mounted() {
console.log('DOM已挂载完成')
// 可以在这里操作DOM元素
},
updated() {
console.log('数据更新,视图已重新渲染')
},
destroyed() {
console.log('实例已销毁')
}
})

理解 Vue

Vue 的核心设计思想是 MVVM (Model-View-ViewModel)

用 Java 概念对标一下

假设我们要做一个 “用户信息展示” 的功能。

  1. 数据层 (Model)

    • Java: 你定义了一个 User 类(POJO),里面有 username, age

    • Vue: 在 Vue 组件里,有一个 data() 方法,返回一个对象。

      1
      2
      3
      4
      5
      6
      7
      // Vue 代码
      data() {
      return {
      username: "ergou",
      age: 18
      }
      }

理解:这就是前端的 POJO,它是页面的“数据源”。

  1. 视图层 (View)

    • Java: Thymeleaf 里的 <span th:text="${user.username}"></span>

    • Vue: Vue 的 <template> 标签。

      1
      2
      3
      4
      5
      <!-- Vue 模板 -->
      <div>
      <p>姓名:{{ username }}</p>
      <p>年龄:{{ age }}</p>
      </div>

理解:这就相当于前端的 HTML 模板,但是它直接绑定了上面的 data。

  1. 逻辑/控制层 (ViewModel - 核心魔法)

    • Java: 你需要写代码:user.setName("ergoutree"),然后重新渲染视图。

    • Vue (双向绑定): 这是 Vue 最爽的地方! 你只需要修改 this.username = "ergoutree",页面上的文字自动就变了。你不需要操作 DOM(不需要写 document.getElementById)。 理解:Vue 就像在这个 POJO 上加了 Spring AOP 的监听,数据一变,它自动帮你更新 HTML。

一个 .vue 文件(单文件组件)其实就是一个完整的模块,结构非常像一个 Java 类:

image-20251120204938895

感觉我没说明白?继续说

为什么我改了数据,界面就变了?

在 Java 里,普通的 POJO 是“死的”,你改了它的属性,它的属性就会被改变)))))(除了属性变了,什么都不会发生)

1
2
3
// Java 普通对象
User user = new User();
user.setName("Ergou"); // 仅仅是内存里的 String 变了,没人知道

但是在 Vue 里,data()返回的对象是被劫持的。

把 Vue 初始化 data 的过程,想象成 Spring 在启动时创建 Bean 的过程:

Vue 2.x 原理:相当于使用了 Java 的 Setter 拦截

Vue 遍历了你 data 里的所有属性,用 JS 的 Object.defineProperty(类似 Java 的 setter 方法)把它们全部重写了。

1
2
3
4
5
6
7
8
9
10
11
// Vue 在背后偷偷把你的 POJO 改造成了这样:
public class UserProxy extends User {
private String username;

@Override
public void setUsername(String username) {
super.setUsername(username);
// 重点在这里!Vue 埋入了自己的钩子
DOMManager.updateTextNodesBoundTo("username", username);
}
}

Vue 3.x 原理:相当于使用了 Java 的动态代理 (InvocationHandler / CGLIB)。 它使用了 JS 的 Proxy 对象,直接拦截了对对象的所有操作。

这个太牛逼了,后面学的时候细说

所以说,Vue 的 data 不是简单的存放数据的容器,它是一个被监控的响应式系统。你以为你在赋值 this.username = "xx",实际上你触发了一连串的回调函数,引起了通知视图更新。

Vue 的 <template> 标签中,你看到的 <template> 标签里写的是 HTML,但浏览器是不认识 .vue 文件的。

JSP 原理:Tomcat 会把 .jsp 文件翻译成 .java (Servlet),然后编译成 .class 运行。

1
2
// JSP 编译后的 Servlet 代码片段
out.write("<div>姓名:" + user.getUsername() + "</div>");

Vue 原理:Vue 的编译器(类似 javac)会把 <template>里的 HTML 编译成 JS 渲染函数 (Render Function)

当你在模板里写<p>{{ username }}</p> 时,Vue 把它编译成了类似这样的 JS 代码:

1
2
3
4
// 这就是 Vue 真正运行时的逻辑
function render() {
return createElement('p', this.username); // 创建一个 P 标签,内容绑定 this.username
}
  1. Vue 组件加载时,执行这个 render 函数。
  2. 函数读取了 this.username。
  3. 因为 this.username 是被代理过的(见第一点),它察觉到“有人在读我”,于是把当前的渲染任务记录下来(依赖收集)。
  4. 当你下次修改 this.username 时,它根据记录,通知 render 函数重新执行,生成新的 Virtual DOM,然后更新界面。

在 jQuery 时代或者原生 JS 时代,前端写代码是命令式的:

“找到那个 ID 为 btn 的按钮,给它绑个事件;找到 ID 为 name 的输入框,把它的值改成 ABC…”

这就像你在 Java 里不使用 Hibernate/MyBatis,而是手动拼接 SQL 字符串,手动 ResultSet.get(“name”),非常累且容易出错。

Vue 的 MVVM 是声明式的:

“我的数据状态是 isLoading = true。”

Vue 框架(容器)会自动去更新界面,把加载转圈显示出来。这就好比 Hibernate:

“我把 User 对象的 name 改了,save 一下。”

Hibernate 自动帮你生成 SQL 去更新数据库。

  • Java Hibernate/MyBatis: Java Object ↔︎ Database Table
  • Vue.js: JS Object ↔︎ HTML DOM

现在,当你看着那个 data() 和 template,是不是感觉它其实就是一个自带了自动同步数据库(DOM)功能的 Java 类?

Vue结构框架

我们已经知道了Vue.js是典型的MVVM框架,那么我好像还没有细说什么是 MVVM 框架

image-20251121154700876

可以看出,它是对 MVC 框架的一个改进,其架构分为三个核心部分:

  • View(视图):对应页面的 DOM 结构,是用户可见的界面,负责展示数据和响应用户操作。
  • ViewModel(视图模型):是 View 和 Model 之间的 “桥梁”,在 Vue 中体现为 Vue 实例(包含数据、方法、计算属性等)。它通过数据绑定(将 Model 的数据同步到 View)和事件监听(将 View 的操作同步到 Model),实现 View 和 Model 的双向通信,让开发者无需手动操作 DOM,只需关注数据逻辑。
  • Model(模型):对应应用的业务数据和逻辑,通常是 JavaScript 对象(如后端接口返回的数据、本地定义的业务对象),是应用的 “数据源”。

传统 MVC(Model-View-Controller)中,Controller 负责协调 View 和 Model 的交互,开发者需手动处理 DOM 操作和数据同步。而 MVVM 通过 ViewModel 的双向绑定,让数据变化自动反映到视图,视图操作也自动更新数据,减少了手动操作 DOM 的工作量,使代码更聚焦于业务逻辑,提升了开发效率和代码可维护性。

所以 MVVM 流行起来了

image-20251121154616426

Vue 的程序结构主要分为 instance(实例)global(全局) 两部分:

  • instance(Vue 实例)

    Vue 实例是 Vue 应用的核心,每个 Vue 应用都是通过构造函数Vue创建实例启动的。它包含两部分关键内容:

    • api(实例方法 / 接口)
      • data:管理组件的响应式数据,数据变化时会触发视图更新。
      • dom:操作 DOM 的相关方法,比如$el(获取实例对应的 DOM 元素)。
      • event:事件相关方法,如$on(监听事件)、$emit(触发事件)。
      • lifecycle:生命周期钩子方法,如created(实例创建完成)、mounted(DOM 挂载完成)等,用于在不同阶段执行自定义逻辑。
    • init(初始化配置)
      • data:定义实例的初始数据(支持对象或函数形式,组件中必须用函数避免数据污染)。
      • template:定义实例的模板,Vue 会将模板编译为渲染函数,最终生成 DOM。
  • global(全局配置)

    用于配置 Vue 的全局行为,包含:

    • api(全局方法 / 接口):如Vue.extend(创建组件构造器)、Vue.component(注册全局组件)等。
    • options(全局选项)
      • directives:注册全局自定义指令,如Vue.directive('focus', { inserted: el => el.focus() })
      • filters:注册全局过滤器,用于格式化数据,如Vue.filter('formatTime', value => /* 时间格式化逻辑 */)

Vue的安装

一般情况下。我们使用 npm 在全局引入 Vue

1
2
3
4
5
6
7
8
9
10
11
# 安装Vue CLI (Vue官方脚手架)
npm install -g @vue/cli

# 创建第一个Vue项目
vue create my-first-vue-app

# 进入项目目录
cd my-first-vue-app

# 启动开发服务器
npm run serve

而且可以使用 npm create 命令创建项目,格式如下:

1
npm create vite@latest <project-name> --template vue

其中,

  • npm create :用于执行项目模板的命令,它会创建一个新的项目,并从给定的模板中初始化。
  • vite@latest :vite 是创建 Vue 3 项目的工具,@latest 是指定使用最新版的 Vite,确保你创建的项目是基于最新版本的 Vite。如果没有 @latestnpm 会尝试使用当前安装的版本。
  • <project-name>:新创建项目的文件夹名称。命令会创建一个文件夹,并将模板代码放入其中。例如,运行 npm create vite@latest my-vue-app --template vue 会在当前目录下创建一个名为 my-vue-app 的文件夹,并将 Vue 项目的模板文件放入其中。
  • --template vue--template vue 指定了要使用的模板类型。Vite 支持多种模板,vue 是专门为 Vue 3 提供的模板。还有其他模板,如 vanillareactsvelte 等。

创建项目后的目录结构如图

image-20251122103934868

启动前需要安装依赖,npm install,然后启动开发服务器之后,会显示你的端口和访问地址,一般是 5173

image-20251120210233109

另外我们可以在 vite.config.js 文件中设置自己的端口

1
2
3
4
5
6
7
8
9
10
11
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
plugins: [vue()],

server: {
port: 3000, // 自己规定的端口号
},
})

注意,Vue.js 不支持 IE8 及其以下 IE 版本。

虽然我们也可以在 Vue.js 的官网上直接下载最新版本, 并用 **<script>**标签引入。

https://unpkg.com/vue@3/dist/vue.global.js

对了,我们也可以通过 vue ui 命令来打开图形化界面创建和管理项目

1
vue ui

执行以上命令会在浏览器中打开一个图形化界面来引导项目创建:

image-20251120210306215

什么是 Vite

作为 Java 后端开发者,你肯定经历过这样的痛苦:

项目很大,每次改几行代码,重启 Spring Boot 或者重新部署 Tomcat 都要等个几十秒一分钟的。

后来有了 JRebel 这种热部署工具,和IDEA后来支持Debug下的热部署,爽度才提升了一些。

而你前端改动肯定更加频繁,Vite 的出现,就是为了解决前端界的这个问题。

Vite (法语,意为“快”,发音 /vit/) 是一个前端构建工具 + 开发服务器

在 Vite 出现之前,主流工具是 Webpack

  • Webpack (老模式):类似于 Java 的 Full Build

    哪怕你只改了一行代码,它也要把所有 JS 文件读一遍,重新打包成一个大 bundle.js,然后喂给浏览器。项目越大,启动和热更新越慢(类似大型单体应用重启)。

  • Vite (新模式):类似于 Java 的 Class Loading on Demand (按需加载)。

    Vite 利用了现代浏览器本身支持 import (ES Modules) 的特性。

    • 当你打开首页,浏览器说:“我需要 Home.vue”。
    • Vite 说:“好,我现编一下 Home.vue 给你。”
    • 浏览器说:“我需要 User.js”。
    • Vite 说:“给。”
    • 结论:它不打包,你需要什么它给什么。所以项目再大,启动速度都是毫秒级的

常用命令

  • 开发环境 (npm run dev): 使用 ESBuild(Go 语言写的神器),不做打包,只做简单的转译,速度快到飞起。
  • 生产环境 (npm run build): 使用 Rollup 进行打包。因为浏览器环境复杂,为了兼容性和加载速度,上线前还是要把所有代码压缩、混淆、合并成静态文件(类似打成 WAR/JAR 包)

那么看一下 Vue 项目用 Vite 构建的生命周期命令

  • 项目创建

    1
    npm create vue@latest
    1. 这个命令会启动一个交互式脚手架(类似 Spring Initializr)。

    2. 让你选要不要 TypeScript (强类型)、Vue Router (路由)、Pinia (状态管理) 等。

    3. 最后生成一个文件夹,里面有 package.json (pom.xml) 和基础代码。

    4. 在创建项目的时候,Vite 支持多个模板,常见的有:

      vue: Vue 3 项目(默认使用 Vue 3)

      vanilla: 无框架的基本模板

      react: React 项目

      svelte: Svelte 项目

      preact: Preact 项目

  • 依赖安装

    1
    npm install (或 npm i)
    1. 读取 package.json 里的 dependenciesdevDependencies
    2. 去 npm 远程仓库下载包。
    3. 关键点:下载的文件会放在项目根目录下的 node_modules 文件夹里。
      • 理解:node_modules 就是你的项目级 .m2 仓库或 WEB-INF/lib。
  • 开发启动

    1
    npm run dev
    1. Vite 启动一个本地服务器 (默认端口 5173)。
    2. 注意:此时不会生成任何物理文件(没有 dist 目录),所有编译都在内存中进行。
    3. HMR (热模块替换):当你修改了 .vue 文件并保存,Vite 会通过 WebSocket 通知浏览器,浏览器只替换那一个组件,页面不刷新,状态不丢失
      • 理解:这是最高级的 JRebel,改了代码,网页上的弹窗都不会关,内容直接变。
  • 生产打包

    1
    npm run build
    1. Vite 调用 Rollup。

    2. Tree Shaking (摇树优化):把你代码里没用到的死代码(Dead Code)自动删掉,减小体积。

    3. Minification (压缩):把变量名改成 a, b, c,去掉空格注释,压缩体积。

    4. Output: 生成一个 dist 文件夹,该目录一般包含 index.html 文件及 static 目录,static 目录包含了静态文件 js、css 以及图片目录 images(如果有图片的话)。

      • 理解:dist 文件夹就是你的 target/app.war。它里面全是静态资源(html, css, js),这玩意儿已经跟 Vue 没关系了,浏览器直接能认。
      image-20251122103741466
  • 本地预览

    1
    npm run preview
    1. Vite 启动一个模拟线上的服务器,专门运行 dist 文件夹里的内容。
    2. 注意:这不是开发环境,不能热更新,用来测试上线前的最终效果。

配置文件对照

image-20251120210956573

说都说这个了,多说一句 vite.config.ts 里的跨域代理

前端跑在 localhost:5173,后端 Spring Boot 跑在 localhost:8080。

前端发请求给后端,浏览器会报 CORS 跨域错误

所以我们会在 vite.config.ts 里配置反向代理(相当于 Vite 内置了一个 Nginx)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
plugins: [vue()],
server: {
port: 5173, // 前端端口
// 代理配置:这就相当于 Nginx 的 proxy_pass
proxy: {
'/api': {
target: 'http://localhost:8080', // 后端 Spring Boot 地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
// 把 /api/user 变成 /user 发给 8080
}
}
}
})