VUE+SPRINGBOOT从0-1打造前后端-前后台系统-用户管理

在现代Web应用开发中,前后端分离架构已经成为主流模式。本文将通过一个完整的用户管理系统案例,详细介绍如何使用Vue.js + Element UI构建前端界面,结合Spring Boot实现后端服务,实现前后端分离开发。该系统包含用户信息的增删改查、批量操作、导入导出等常见功能,是一个典型的企业级管理系统模块。

一、技术栈介绍

1.1 前端技术栈

  • Vue.js:渐进式JavaScript框架,用于构建用户界面

  • Element UI:基于Vue.js的桌面端组件库,提供丰富的UI组件

  • Axios:基于Promise的HTTP客户端,用于前后端通信

  • Vue Router:Vue.js官方的路由管理器

1.2 后端技术栈

  • Spring Boot:简化Spring应用初始搭建和开发过程的框架

  • MyBatis-Plus:MyBatis的增强工具,简化CRUD操作

  • Hutool:Java工具类库,提供Excel导入导出等功能

  • JWT:用于身份验证的JSON Web Token

二、前端实现详解

2.1 项目结构与配置

前端项目采用Vue CLI搭建,主要目录结构如下:

src/
├── views/
│   └── User.vue       # 用户管理主页面
├── router/            # 路由配置
├── api/               # API请求封装
└── public/config.js   # 全局配置

public/config.js中配置后端服务地址:

window.WHITE_IP = "your-server-ip:port";

2.2 用户管理页面布局

用户管理页面主要分为以下几个部分:

  1. 搜索区域:提供用户名搜索和重置功能

  2. 操作按钮区域:新增、批量删除、导入导出等功能按钮

  3. 表格展示区域:用户数据列表展示

  4. 分页组件:数据分页控制

  5. 弹窗表单:新增/编辑用户信息

<div class="User-container"><!-- 搜索区域 --><div style="margin: 10px 0"><el-input v-model="send.name" placeholder="请输入用户名"></el-input><el-button @click="selectListPage">搜索</el-button><el-button @click="reset">重置</el-button><!-- 操作按钮 --><el-button @click="insertWindow">新增</el-button><el-popconfirm @confirm="confirmRemoveIdList"><el-button slot="reference">批量删除</el-button></el-popconfirm><el-button @click="list_export">导出</el-button></div><!-- 表格区域 --><el-table :data="list" @selection-change="onSelectChange"><!-- 表格列定义 --></el-table><!-- 分页组件 --><el-pagination@size-change="onSizeChange"@current-change="onCurrentChange":current-page="send.currentPage":page-size="send.pageSize":total="send.total"></el-pagination><!-- 弹窗表单 --><el-dialog :visible.sync="sendFormFlag"><el-form><!-- 表单字段 --></el-form></el-dialog>
</div>

2.3 核心功能实现

2.3.1 分页查询

分页查询是管理系统的核心功能,前端需要维护当前页码、每页条数等参数:

data() {return {send: {currentPage: 1,pageSize: 10,total: 0,name: ''},list: []}
},
methods: {// 分页查询selectListPage() {this.$http.post("/user/list_page", this.send).then(res => {if (res.data.code === "200") {this.send.total = res.data.object.totalthis.list = res.data.object.data}})},// 分页大小变化onSizeChange(pageSize) {this.send.pageSize = pageSizethis.selectListPage()},// 当前页变化onCurrentChange(currentPage) {this.send.currentPage = currentPagethis.selectListPage()}
}
2.3.2 新增与编辑用户

通过同一个弹窗表单实现新增和编辑功能:

methods: {// 打开新增窗口insertWindow() {this.sendFormFlag = truethis.sendForm = {}},// 打开编辑窗口updateWindow(row) {this.sendFormFlag = truethis.sendForm = JSON.parse(JSON.stringify(row))},// 确认保存confirmInsertOrUpdate() {this.$http.post("/user/insertOrUpdate", this.sendForm).then(res => {if (res.data.code === "200") {this.$message.success('保存成功')this.selectListPage()}})}
}
2.3.3 批量操作

批量操作需要处理表格的多选功能:

methods: {// 多选变化onSelectChange(val) {this.sendForm.removeIdList = val},// 确认批量删除confirmRemoveIdList() {this.sendForm.removeIdList = this.sendForm.removeIdList.map(v => v.id)this.$http.post("user/list_delete", this.sendForm).then(res => {this.selectListPage()})}
}
2.3.4 导入导出功能

导入导出是管理系统常见功能,使用Element UI的Upload组件实现:

methods: {// 导出list_export() {window.open(`https://${WHITE_IP}/user/list_export`)},// 导入成功回调onImportSuccess() {this.$message.success("文件导入成功")this.selectListPage()}
}

三、后端实现详解

3.1 项目结构

后端采用标准的Spring Boot项目结构:

src/main/java/
└── com.black├── controller    # 控制器层├── mapper        # 数据访问层├── pojo          # 实体类└── util         # 工具类

3.2 核心控制器实现

用户控制器处理所有用户相关的请求:

@RestController
@RequestMapping("/user")
public class UserController {@ResourceUserMapper userMapper;// 新增或更新用户@PostMapping("/insertOrUpdate")public Res insertOrUpdate(@RequestBody User user) {if (user.getId() != null) {userMapper.updateById(user);} else {user.setPassword(MyUtils.getSHA256StrJava("123456"));userMapper.insert(user);}return Res.success(null);}// 分页查询@PostMapping("/list_page")public Res list_page(@RequestBody User user) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();if (StringUtils.isNotBlank(user.getName())) {queryWrapper.like("name", user.getName());}int total = userMapper.selectCount(queryWrapper);queryWrapper.last("limit " + user.getStart() + "," + user.getEnd());List<User> dataList = userMapper.selectList(queryWrapper);Map<String, Object> result = new HashMap<>();result.put("total", total);result.put("data", dataList);return Res.success(result);}// 导出Excel@GetMapping("/list_export")public void list_export(HttpServletResponse response) throws Exception {List<User> list = userMapper.selectList(null);ExcelWriter writer = ExcelUtil.getWriter(true);// 设置标题别名writer.addHeaderAlias("id", "ID");writer.addHeaderAlias("name", "用户名");// ...其他字段writer.write(list, true);response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");String fileName = URLEncoder.encode("用户信息", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");ServletOutputStream out = response.getOutputStream();writer.flush(out, true);out.close();writer.close();}
}

3.3 分页查询实现

后端分页查询使用MyBatis-Plus实现:

@PostMapping("/list_page")
public Res list_page(@RequestBody User user) {// 1. 构建查询条件QueryWrapper<User> queryWrapper = new QueryWrapper<>();if (StringUtils.isNotBlank(user.getName())) {queryWrapper.like("name", user.getName());}// 2. 获取总数int total = userMapper.selectCount(queryWrapper);// 3. 计算分页参数int start = (user.getCurrentPage() - 1) * user.getPageSize();int end = user.getPageSize();// 4. 执行分页查询queryWrapper.last("limit " + start + "," + end);List<User> dataList = userMapper.selectList(queryWrapper);// 5. 返回结果Map<String, Object> result = new HashMap<>();result.put("total", total);result.put("data", dataList);return Res.success(result);
}

3.4 Excel导出实现

使用Hutool工具库实现Excel导出:

@GetMapping("/list_export")
public void list_export(HttpServletResponse response) throws Exception {// 1. 查询数据List<User> list = userMapper.selectList(null);// 2. 创建Excel写入器ExcelWriter writer = ExcelUtil.getWriter(true);// 3. 设置标题别名writer.addHeaderAlias("id", "ID");writer.addHeaderAlias("name", "用户名");writer.addHeaderAlias("nick", "昵称");// ...其他字段// 4. 写入数据writer.write(list, true);// 5. 设置响应头response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");String fileName = URLEncoder.encode("用户信息", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");// 6. 输出流ServletOutputStream out = response.getOutputStream();writer.flush(out, true);out.close();writer.close();
}

四、前后端交互设计

4.1 API接口规范

系统采用RESTful风格设计API,主要接口如下:

请求方法路径描述
POST/user/list_page分页查询用户列表
POST/user/insertOrUpdate新增或更新用户
POST/user/delete删除用户
POST/user/list_delete批量删除用户
GET/user/list_export导出用户数据到Excel

4.2 数据格式约定

前后端统一使用JSON格式交互,响应数据格式如下:

成功响应:

{"code": "200","message": "成功","object": {"total": 100,"data": [...]}
}

错误响应:

{"code": "500","message": "服务器错误"
}

4.3 Axios封装

对Axios进行统一封装,处理请求和响应:

import axios from 'axios'
import router from '../router'// 创建axios实例
const service = axios.create({baseURL: process.env.BASE_API,timeout: 5000
})// 请求拦截器
service.interceptors.request.use(config => {// 在请求头中添加tokenif (localStorage.token) {config.headers['Authorization'] = localStorage.token}return config},error => {return Promise.reject(error)}
)// 响应拦截器
service.interceptors.response.use(response => {const res = response.dataif (res.code !== '200') {// token过期处理if (res.code === '401') {router.push('/login')}return Promise.reject(res)} else {return res.object}},error => {return Promise.reject(error)}
)export default service

五、系统安全考虑

5.1 密码安全

用户密码使用SHA256加密存储:

public class MyUtils {public static String getSHA256StrJava(String str) {try {MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hash = digest.digest(str.getBytes(StandardCharsets.UTF_8));StringBuilder hexString = new StringBuilder();for (byte b : hash) {String hex = Integer.toHexString(0xff & b);if (hex.length() == 1) hexString.append('0');hexString.append(hex);}return hexString.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}
}

5.2 接口权限控制

使用JWT进行接口权限验证:

public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (token == null) {throw new RuntimeException("无token,请重新登录");}// 验证tokenClaims claims = JwtUtil.parseToken(token);if (claims == null) {throw new RuntimeException("token不合法");}// 将用户信息存入requestrequest.setAttribute("userInfo", claims.get("userInfo"));return true;}
}

5.3 XSS防护

对用户输入进行过滤,防止XSS攻击:

public class XssFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(httpRequest);chain.doFilter(xssRequest, response);}
}public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String getParameter(String name) {String value = super.getParameter(name);return cleanXSS(value);}private String cleanXSS(String value) {if (value == null) return null;return HtmlUtils.htmlEscape(value);}
}

六、性能优化实践

6.1 前端性能优化

  1. 组件懒加载:路由组件按需加载

  2. 表格虚拟滚动:大数据量表格使用虚拟滚动

  3. 请求防抖:搜索框输入使用防抖处理

// 防抖处理
debounceSelectListPage: _.debounce(function() {this.selectListPage()
}, 500)

6.2 后端性能优化

  1. MyBatis二级缓存:启用MyBatis二级缓存减少数据库查询

  2. 分页优化:使用更高效的分页查询方式

  3. 批量操作:使用批量插入代替循环单条插入

// 批量插入示例
public void batchInsert(List<User> userList) {SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);UserMapper mapper = session.getMapper(UserMapper.class);for (User user : userList) {mapper.insert(user);}session.commit();session.clearCache();session.close();
}

七、总结与扩展

本文详细介绍了基于Vue.js和Spring Boot的前后端分离用户管理系统的实现。系统实现了用户管理的常见功能,包括:

  1. 用户信息的增删改查

  2. 批量操作

  3. 数据导入导出

  4. 分页查询与条件过滤

  5. 系统安全防护

扩展方向

  1. 角色权限管理:实现更细粒度的权限控制

  2. 操作日志:记录用户操作日志

  3. 数据可视化:增加用户数据统计图表

  4. 消息通知:系统消息通知功能

  5. 移动端适配:开发响应式布局或单独移动端应用

通过这个项目,开发者可以掌握前后端分离开发的核心技术栈,了解企业级应用开发的常见模式和最佳实践。希望本文能为您的开发工作提供有价值的参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93252.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93252.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于uni-app+vue3实现的微信小程序地图范围限制与单点标记功能实现指南

一、功能概述本文将分步骤讲解如何使用uni-app框架在微信小程序中实现以下功能&#xff1a;显示基础地图绘制特定区域范围&#xff08;以郑州市为例&#xff09;实现点击地图添加标记点限制标记点只能在指定区域内添加显示选中位置的坐标信息二、分步骤实现步骤1&#xff1a;搭…

C# 反射和特性(关于应用特性的更多内容)

关于应用特性的更多内容 至此&#xff0c;我们演示了特性的简单使用&#xff0c;都是为方法应用单个特性。本节将讲述特性的其他使 用方式。 多个特性 可以为单个结构应用多个特性。 多个特性可以使用下面任何一种格式列出。 独立的特性片段一个接一个。通常&#xff0c;它们彼…

【iOS】KVC原理及自定义

目录 前言 KVC定义及API KVC的使用 基本类型 集合类型 访问非对象类型——结构体 集合操作符 层层嵌套 KVC底层原理 设值过程 取值过程 自定义KVC setter方法 getter方法 KVC异常小技巧 自动转换类型 设置空值 未定义的key 前言 在平时的开发中我们经常用到K…

完整设计 之 智能合约系统:主题约定、代理协议和智能合约 (临时命名)----PromptPilot (助手)答问之2

摘要&#xff08;CSDN的AI助手生成的&#xff09;智能合约系统架构设计摘要本设计构建了一个多层次智能合约系统&#xff0c;包含150字以内的核心架构&#xff1a;三级架构体系&#xff1a;元级&#xff08;序分&#xff09;&#xff1a;MetaModel合约定义系统核心原则模型级&a…

Java基础 8.16

1.final关键字基本介绍final中文意思&#xff1a;最后的&#xff0c;最终的final可以修饰类、属性、方法和局部变量在某些情况下&#xff0c;程序员可能有以下需求&#xff0c;就会使用到final当不希望类被继承时,可以用final修饰当不希望父类的某个方法被子类覆盖/重写(overri…

YOLOv8目标检测网络结构理论

目录 YOLOv8的网络结构图&#xff1a; Backbone 卷积块&#xff08;Conv Block&#xff09; Conv2d层 BatchNorm2d层 SiLU激活函数 瓶颈块(Bottleneck Block) C2f 模块结构 Neck SPPF(空间金字塔池化快速) PAN - FPN Head 结构1.卷积层和激活函数: 2.预测层(Predi…

docker部署hadoop集群

Docker部署hadoop集群下载资源构建镜像启动容器搭建集群配置ssh免密节点职责安排修改配置文件启动集群测试上传下载执行wordcount程序补充配置历史服务器日志聚集单节点启动Java客户端使用HDFSMapReduce下载资源 java华为镜像下载地址&#xff1a;Index of java-local/jdk (hu…

常用的T-SQL命令

文章目录1. 数据库操作2. 表操作3. 数据插入、更新、删除4. 数据查询5. 存储过程6. 事务处理7、如何使用T-SQL在表中设置主键和外键&#xff1f;1. 设置主键&#xff08;PRIMARY KEY&#xff09;方法1&#xff1a;创建表时定义主键方法2&#xff1a;通过ALTER TABLE添加主键2. …

C++面试题及详细答案100道( 31-40 )

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

给纯小白的 Python 操作 Excel 笔记

&#x1f9f0; 1. 先装工具电脑键盘按 Win R&#xff0c;输入 cmd&#xff0c;回车&#xff0c;把下面一行粘进去回车&#xff0c;等它跑完。 bashpip install openpyxl——————————————————&#x1f6e0;️ 2. 打开一个空白的 Excel 打开 Jupyter Notebook…

HTML 常用属性介绍

目录 HTML 属性 HTML 属性速查表 一、通用属性&#xff08;所有元素适用&#xff09; 二、链接与引用相关属性 三、表单与输入控件属性 四、媒体与多媒体属性 五、事件属性&#xff08;常用 JavaScript 事件&#xff09; 六、其他常用属性 核心通用属性 id 属性 cla…

HTML5练习代码集:学习与实践核心特性

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;HTML5作为新一代网页标准&#xff0c;对Web开发提供了更丰富的功能和工具。本练习代码集专门针对HTML5的核心特性&#xff0c;包括语义化标签、离线存储、多媒体支持、图形绘制等&#xff0c;以及CSS3的3D效果和…

【RH134知识点问答题】第 10 章:控制启动过程

目录 1. 请简要说明 RHEL9 的启动过程。 2. 系统重启和关机的命令分别是什么? 3. Systemd target 是什么&#xff1f; 4. 重置丢失的 root 密码需要哪些步骤&#xff1f; 5. 如何让系统日志在重启后持久保留 1. 请简要说明 RHEL9 的启动过程。 答&#xff1a;①开机自检…

Apollo10.0学习之固态雷达与IMU的外参标定

固态雷达&#xff08;如Livox、禾赛等非旋转式激光雷达&#xff09;与IMU&#xff08;惯性测量单元&#xff09;的外参标定&#xff08;Extrinsic Calibration&#xff09;是自动驾驶、机器人定位&#xff08;如LIO-SAM、FAST-LIO&#xff09;的关键步骤。1. 标定原理 外参标定…

HTML5实现古典音乐网站源码模板1

文章目录 1.设计来源1.1 网站首页1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;http…

40 C++ STL模板库9-容器2-vector

C STL模板库9-容器2-vector 文章目录C STL模板库9-容器2-vector一、基础概念1. 类型成员&#xff08;Type Members&#xff09;2. 模板参数二、构造函数1. 语法2. 示例三、元素访问1. 函数说明2. 示例代码四、容量操作1. 函数说明2. 关键点说明3. 关键操作解析4. 操作示例五、修…

GPT-5系列文章2——新功能、测试与性能基准全解析

引言 2025年8月&#xff0c;OpenAI正式发布了其新一代旗舰模型GPT-5。与业界此前期待的AGI(人工通用智能)突破不同&#xff0c;GPT-5更像是OpenAI对现有技术的一次深度整合与用户体验优化。本文将全面解析GPT-5的新特性、实际测试表现以及官方发布的基准数据&#xff0c;帮助开…

利用cursor+MCP实现浏览器自动化释放双手

小伙伴们&#xff0c;我们今天利用cursorMCP实现浏览器自动化&#xff0c;释放双手&#xff0c;工作效率嘎嘎提升&#xff01;前期准备&#xff1a;安装node.js网址&#xff1a;https://nodejs.org/zh-cn下载下来安装即可。 下载browser-tools-mcp扩展程序&#xff1a;下载扩展…

指针/边界索引混淆梳理

在处理数组/链表等数据结构时&#xff0c;时常混淆长度和指针序号。处理技巧&#xff1a;使用0-base索引。则区间长度 rightIndex - LeftIndex 1总长度 lastIndex - firstIndex 1链表创建一个dummy节点&#xff0c;添加到head前&#xff0c;则可认为从索引0开始。末尾指针判…

LeetCode 刷题【43. 字符串相乘】

43. 字符串相乘 自己做 解1&#xff1a;矩阵计数 class Solution { public:string multiply(string num1, string num2) {int len1 num1.size();int len2 num2.size();if (num1[0] 0 || num2[0] 0) //结果为0的情况return "0";//存储计算过程的矩阵vector…