Vue 学习总结(Java 后端工程师视角)

基于前后端分离项目(Vue3 + Vite + TypeScript + Pinia + Element Plus)全程类比 SpringBoot 思维,新手可直接上手

一、项目结构与核心文件作用

1. 整体结构

plaintext

java 复制代码
项目根目录
├── .vscode/           VSCode 编辑器配置
├── node_modules/      第三方依赖库(≈ Maven 本地仓库)
├── public/            静态资源(≈ SpringBoot static)
├── src/               业务源码(主要开发目录)
├── dist/              打包后部署文件(≈ target/)
├── package.json       依赖 + 启动脚本(≈ pom.xml)
└── index.html         项目入口页面

2. 关键文件说明

  • package.json :管理依赖、定义 dev/build/lint 等命令
  • node_modules/npm install 生成,不提交 Git
  • dist/npm run build 后生成,用于部署
  • public/ :存放 favicon.ico 等不参与编译的静态资源
  • src/ :页面、组件、接口、状态、路由均在此

二、项目运行与启动流程

1. 常用命令

bash

运行

arduino 复制代码
npm run dev      # 启动开发服务(≈ mvn spring-boot:run)
npm run build    # 生产打包(≈ mvn clean package)
npm install      # 安装依赖

2. 浏览器启动 Vue 流程

  1. 访问地址 → 加载 index.html
  2. 解析并加载 main.ts(项目入口)
  3. 创建 Vue 实例,挂载到 #app 节点
  4. 加载路由 → 根据 URL 渲染对应页面

3. 入口文件 main.ts(≈ 启动类)

ts

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'

const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')

三、Pinia 状态管理(核心重点)

1. 是什么?

Pinia = 前端的 @Service + 全局单例 Bean + 内存缓存用于:全局共享数据、业务逻辑封装、接口调用、权限状态。

2. 基本结构

ts

javascript 复制代码
import { defineStore } from 'pinia'

export const useXxxStore = defineStore('唯一标识', {
  state: () => ({
    // 数据 ≈ 类成员变量
  }),
  actions: {
    // 方法 ≈ 业务逻辑(支持 async/await)
  },
  getters: {
    // 计算属性 ≈ getXxx()
  }
})

3. async /await 说明

  • async:标记为异步方法
  • await:等待异步操作完成(如接口请求)
  • 本质:异步执行,但写法像同步,避免回调嵌套

四、前后端分离接口封装

1. API 层(≈ Mapper / Dao)

ts

typescript 复制代码
// src/api/student.ts
import request from './index'

export interface Student {
  id: number
  name: string
  className: string
}

export function getStudentList(params: { page: number; pageSize: number }) {
  return request<{ list: Student[]; total: number }>({
    url: '/student/list',
    method: 'get',
    params
  })
}

2. 请求工具统一携带 Token

ts

javascript 复制代码
// src/api/index.ts
import axios from 'axios'
import { useAuthStore } from '@/stores/authStore'

const request = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL
})

// 请求拦截器自动加 token
request.interceptors.request.use(config => {
  const authStore = useAuthStore()
  if (authStore.token) {
    config.headers.Authorization = `Bearer ${authStore.token}`
  }
  return config
})

export default request

五、路由 Vue Router(≈ @RequestMapping)

配置示例

ts

javascript 复制代码
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/student',
    component: () => import('@/views/StudentList.vue'),
    meta: { requiresAuth: true }
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

六、完整可运行示例:学生管理

1. 学生 Store(≈ Service)

ts

javascript 复制代码
// src/stores/studentStore.ts
import { defineStore } from 'pinia'
import { getStudentList, Student } from '@/api/student'

export const useStudentStore = defineStore('student', {
  state: () => ({
    list: [] as Student[],
    total: 0,
    page: 1,
    pageSize: 10,
    loading: false
  }),

  actions: {
    async fetchList() {
      this.loading = true
      try {
        const res = await getStudentList({
          page: this.page,
          pageSize: this.pageSize
        })
        this.list = res.list
        this.total = res.total
      } finally {
        this.loading = false
      }
    }
  }
})

2. 学生列表页面(≈ Controller + View)

vue

ini 复制代码
// src/views/StudentList.vue
<template>
  <el-card>
    <el-table :data="studentStore.list" v-loading="studentStore.loading">
      <el-table-column label="ID" prop="id" />
      <el-table-column label="姓名" prop="name" />
      <el-table-column label="班级" prop="className" />
    </el-table>

    <el-pagination
      v-model:current-page="studentStore.page"
      v-model:page-size="studentStore.pageSize"
      :total="studentStore.total"
      @current-change="studentStore.fetchList"
      style="margin-top:16px; text-align:right"
    />
  </el-card>
</template>

<script setup lang="ts">
import { useStudentStore } from '@/stores/studentStore'
const studentStore = useStudentStore()

studentStore.fetchList()
</script>

七、全局字典缓存(DictStore)

作用

统一管理性别、班级、状态等下拉数据,全局只请求一次

ts

javascript 复制代码
// src/stores/dictStore.ts
import { defineStore } from 'pinia'
import { getDictData } from '@/api/dict'

export const useDictStore = defineStore('dict', {
  state: () => ({
    gender: [],
    classes: []
  }),

  actions: {
    async loadDict() {
      const res = await getDictData()
      this.gender = res.gender
      this.classes = res.classes
    }
  }
})

使用方式

ts

scss 复制代码
// App.vue 中全局加载一次
const dictStore = useDictStore()
dictStore.loadDict()

// 页面中直接使用缓存
dictStore.gender
dictStore.classes

八、前后端 MVC 对应关系

表格

前端技术 Java 后端对应
Vue 页面 Controller + View
Pinia Store Service 层
API 接口 Mapper / Dao
Pinia state 成员变量 / 缓存
axios RestTemplate / WebClient
Vue Router @RequestMapping
package.json pom.xml
node_modules Maven 依赖库
dist 目录 target 编译目录

九、核心知识点总结

  1. Vue 是前端框架,相当于浏览器里的 SpringBoot
  2. Pinia 是状态管理,相当于全局 Service + 缓存
  3. async/await 用于异步请求后端接口
  4. API 层统一封装接口,便于维护和加 Token
  5. 路由控制页面跳转,类似后端接口路由
  6. 项目结构、分层思想与后端高度一致

十、学习路线(后端工程师推荐)

  1. 项目结构与文件作用
  2. 启动流程与 main.ts
  3. Pinia 基本使用
  4. 接口调用与 axios 封装
  5. 路由与登录权限
  6. 表格、表单、增删改查
  7. 全局字典、缓存、权限控制
相关推荐
এ慕ོ冬℘゜7 分钟前
深度解析 JavaScript:赋予 Web 灵魂的“全栈语言”
开发语言·前端·javascript
iCOD3R9 分钟前
Skill - 3秒生成精美GitHub主页
前端·程序员·ai编程
爱勇宝16 分钟前
《道德经》第5章:生产环境不相信眼泪
前端·后端·架构
掘金者阿豪20 分钟前
LEFT JOIN 凭空消失的背后,是优化器偷偷帮你做了决定
前端·后端
HackTwoHub28 分钟前
AntiDebug Mcp、AI逆向绕过前端,Hook 加密接口,抓取 Vue 路由漏洞,接入 MCP 让 AI 自动化挖掘前端漏洞
前端·vue.js·人工智能·安全·web安全·网络安全·系统安全
Mr_凌宇31 分钟前
AI 应用工程进阶扩展学习笔记 二
前端·面试
Hyyy43 分钟前
Git Worktree 完全讲解
前端·后端·面试
葡萄城技术团队1 小时前
AI 不会淘汰电子表格,反而会让电子表格成为 AI 操作系统
前端·人工智能
BigTopOne1 小时前
Short Put and Short Call
前端
Cache技术分享1 小时前
465. Java 反射 - 获取类的简单名
前端·后端