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. 全局字典、缓存、权限控制
相关推荐
二月龙4 小时前
移动端 H5 页面开发:响应式适配 + 低版本兼容实战指南
前端
小强19884 小时前
HTML5 新表单全解:日期、手机号、颜色选择器
前端
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(二):目录结构、初始化 GIT、设计并开发配置系统
前端·后端·go
鱼人4 小时前
HTML5 本地存储终极指南
前端
超绝大帅哥5 小时前
React的Fiber是什么? Vue为什么不需要Fiber ?
前端
yingyima5 小时前
正则表达式分组与捕获:凌晨3点服务器报警的解决方案
前端
swipe6 小时前
从 0 到 1 理解 React 虚拟列表:定高、不定高与 Canvas 版本完整拆解
前端·javascript·面试
铁皮饭盒6 小时前
Bun执行python代码
前端·javascript·后端
hunterandroid7 小时前
Service 与前台服务:让任务在后台持续运行
前端
米饭同学i7 小时前
深扒 LobsterAI 官网前端动效实现方案:从交互细节到代码实践
前端