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. 全局字典、缓存、权限控制
相关推荐
喵个咪9 小时前
GoWind Toolkit 前端代码生成|Vue3(ElementPlus/Vben)、React(AntDesign)全自动一键生成教程
前端·vue.js·react.js
摆烂大大王10 小时前
玩转 OpenClaw:用 TaskFlow + Heartbeat 打造自动化工作流
前端·人工智能·自动化
zhangxingchao10 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
梦想的颜色10 小时前
TypeScript 完全指南(上):从零开始掌握类型系统
前端·typescript
之歆11 小时前
Day01_ES6+ 专业指南:从基础到实战的现代JavaScript开发(下)
前端·javascript·es6
lichenyang45311 小时前
鸿蒙 MVVM 实战:从 Demo 到工程化,聊聊登录、状态管理与埋点系统设计
前端
IT_陈寒11 小时前
Vite打包时遇到的坑,原来问题出在这里
前端·人工智能·后端
kyriewen11 小时前
AI生成代码快如闪电,但我修了三个小时——它到底帮了谁?
前端·javascript·ai编程
ayqy贾杰12 小时前
基层管理的三板斧,在AI时代行不通了
前端·后端·团队管理
Apifox12 小时前
Apifox 5 月更新|Postman 导入优化、Runner 支持非 root 运行、请求代码自动带鉴权
前端·后端·安全