# springBoot+vue **Repository Path**: yeshenyuewu/springboot-vue ## Basic Information - **Project Name**: springBoot+vue - **Description**: 利用springBoot+vue开发的增删改查 登录功能 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-09-01 - **Last Updated**: 2023-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 个人运动平台项目 项目地址: 个人运动平台项目地址: 前端地址:https://gitee.com/naughtycat/vue_sport 后台地址 : https://gitee.com/naughtycat/java_sport.git ## 1、项目概述 ​ 致力于做一款前后分离的个人健康平台,旨在配合热爱运动和健身的朋友们开发一款能够完成卡路里统计,运动计划编写,科学食物搭配,以及方便与其它朋友交流心得的平台。 ### 1.1 需求分析 #### 1.1.1、痛点分析 ​ 健康平台中有需要许多的第三方数据,比如:运动卡路里的消耗、食品卡路里的提供、以及各种健身运动的卡路里消耗。需要调取大量的api接口,数据库设计考虑用户分级还有管理员权限设置。比如:普通用户和vip查看的内容区分以及功能区分。管理分为超级管理员和普通管理员。 ​ 页面层面使用vue+elementUI开发,分为前台管理员系统和后台业务模块。需要设计的内容有:登录、后台系统(权限管理、运动平台等)、前台业务(卡路里查询,个人计划制定,食品划分等)。 ​ 后台采用SpringBoot+Mybatis开发,需要提前编写各个模块的路由方便分发,创建关系型数据库。大致分为:用户、功能分支、运动列表,计划列表,卡路里列表等。 #### 1.1.2、项目架构 采取前后端分离开发,前端为vue后端为java。使用springBoot做跨域请求 ![](C:\Users\dz_yk\Desktop\个人运动平台\images\基本架构.png) 前端将在vs code中的Tomcat下部署;后端将在IDEA中集成的Tomcat下部署。 ## 2、框架搭建 搭建VUE+SpringBoot环境,并且使用一个登录模块来测试。 ### 2.1、后台环境搭建 #### 2.1.1、创建SpringBoot 项目 使用IDEA快速搭建SpringBoot环境:File--New--Project--Spring Initializr--Next*2--选择模块【WEB(Spring WEB)&&SQL(JDBC API、MyBatis Framework,MySql Driver)】 ![](C:\Users\dz_yk\Desktop\个人运动平台\images\创建springboot-1.png) ![](C:\Users\dz_yk\Desktop\个人运动平台\images\创建springboot-2.png) ![](C:\Users\dz_yk\Desktop\个人运动平台\images\springboot-3.png) 因为mybatis需要一个数据源,所以配置一个application.yml ```yaml #配置数据库连接 spring: datasource: username: root password: xyp166166 driver-class-name: com.mysql.jdbc.Driver #假如时区报错了 就增加一个时区的配置serverTimezone=UTC url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 type: com.alibaba.druid.pool.DruidDataSource #Spring Boot 默认是不注入这些属性值的,需要自己绑定 #druid 数据源专有配置 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入 #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 ``` 启动项目:http://localhost:8088 #### 2.1.2、创建测试路由路径 编写测试Controller,注意返回值和路径映射 ```java @RestController public class TestController { @RequestMapping("/test") public String test(){ return "This is ok."; } } ``` 运行结果: ![](C:\Users\dz_yk\Desktop\个人运动平台\images\测试结果1.png) #### 2.1.3、跨域配置 ```java @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:8080", "null") .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") .maxAge(3600) .allowCredentials(true); } } ``` #### 2.1.4、创建logincontroller ```java @Controller public class LoginController { @Autowired private UserService userService; @CrossOrigin @RequestMapping("/login") @ResponseBody public String login(@RequestBody User user){//我们请求前端传过来数据 需要加@RequestBody才能把数据请求功 System.out.println(user.getUsername()); User user1 = userService.findUserNameAndPaw(user.getUsername(),user.getPassword()); if(user1!=null){ return "success"; } return "error"; } } ``` #### 2.1.5、创建UserService ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User findUserNameAndPaw(String username, String password) { return userMapper.findUserNameAndPaw(username,password); } @Override public List findAll() { return userMapper.findAll(); } @Override public User findUserName(String username) { return userMapper.findUserName(username); } @Override public User findById(Integer id) { return userMapper.findById(id); } @Override public int addUser(User user) { return userMapper.addUser(user); } @Override public int editUser(User user) { return userMapper.editUser(user); } @Override public int deleteUser(Integer id) { return userMapper.deleteUser(id); } @Override public int updateState(Integer id, Boolean state) { return userMapper.updateState(id,state); } } ``` #### 2.1.6、创建UserMapper.xml ```xml UPDATE easyuser SET state = #{state} WHERE id = #{id} INSERT INTO easyuser (username,password,email,role,state) VALUE (#{username},#{password},#{email},#{role},#{state}) UPDATE easyuser SET username = #{username} , password = #{password} , email = #{email} WHERE id = #{id} DELETE FROM easyuser WHERE id = #{id} ``` ### 2.2、前台开发 #### 2.2.1、创建vue项目 win+R输入cmd打开dos,运行命令:vue ui,进入:Vue 项目管理器 ![](C:\Users\dz_yk\Desktop\个人运动平台\images\vue项目管理器.png) 创建项目: ![](C:\Users\dz_yk\Desktop\个人运动平台\images\创建vue项目.png) 手动创建配置,选择功能:Babel、Router、使用配置然后创建项目。添加插件`elementUI` 添加依赖:`axios`、`less-loader`、`less` 然后运行vue项目 ![](C:\Users\dz_yk\Desktop\个人运动平台\images\运行vue.png) ![](C:\Users\dz_yk\Desktop\个人运动平台\images\vue项目默认首页.png) #### 2.2.2、修改项目 App.vue 删除多余分支,删除About.vue和Home.vue文件,剔除index.js的分支。 ```html ``` ```js import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ ] const router = new VueRouter({ routes }) export default router ``` 之后能正常运行。 #### 2.2.3、创建登录页面 创建Login.vue ```html ``` 修改App.vue把app根组件换成``标签,自定义路由,重定向到login,也可以直接配置路径为"/"访问到login.vue ```js const routes = [ { path: '/', redirect:'/login' }, { path: '/login', component: Login }, ``` 添加全局样式:assets/css/global.css ```css /* 全局式样 */ html,body,#app{ height: 100%; margin: 0px; padding: 0px; } ``` main.js里添加全局样式 ```js import './assets/css/global.css'// 添加全局样式 ``` 创建需要的icon文件夹 assets/font ```js import './assets/font/iconfont.css'// 添加font-icon ``` 修改login.vue ```html ``` #### 2.2.4、修改main.js ```js import Vue from 'vue' import App from './App.vue' import router from './router' import './plugins/element.js' import './assets/css/global.css' // 导入iconfront import './assets/font/iconfont.css' // 导入axios import axios from 'axios' // 挂载axios 到Vue的原型prototype的$http Vue.prototype.$http = axios // 设置请求的根路径 axios.defaults.baseURL = "http://localhost:9000/" axios.interceptors.request.use(config => { console.log(config); // 请求头挂载信息 config.headers.Authorization = window.sessionStorage.getItem("flag"); // 在最后必须return config return config; }) Vue.config.productionTip = false new Vue({ router, render: h => h(App) }).$mount('#app') ``` #### 2.2.5、创建Home页面 ```html ``` 添加home的路由后访问。 ## 3、完善登录 ### 3.1.后台开发 #### 3.1.1、创建user实体 | 名称 | 类型 | 描述 | | -------- | ------- | -------- | | id | int | 主键id | | username | String | 用户名 | | password | String | 密码 | | email | String | 邮箱 | | role | String | 角色类型 | | state | boolean | 启用标识 | #### 3.1.2、创建userService 会根据用户输入的`用户名`和`密码`来获取信息,方法名`getUserByMassage` ```java @Repository public int getUserByMassage(@Param("username") String username, @Param("password") String password); ``` #### 3.1.3、编写usermapper mybatis的映射文件 ```xml ``` 查询条件:`SELECT count(id) FROM easyUser WHERE username='xxx' AND password='xxx' AND state = 1` #### 3.1.4、创建UserController 使用传递过来的username和password入参dao的`getUserByMassage`方法 ```java @RequestMapping("/login") public String userLogin(@RequestBody User user) { System.out.println("User : " + user); String str = "error"; int count = userDao.getUserByMassage(user.getUsername(), user.getPassword()); if (count > 0) { str = "ok"; } return str; } ``` 查询结果大于0后,证明查询有结果,登录就应该成功,之前我们页面的判断条件是结果返回是否为“ok”。 ☆ 如果用户名做了去重这里的判断应该是等于1。 #### 3.1.5、路由守卫 首先登录成功后,希望设置一个保存信息。所以修改查询语句: `SELECT * FROM easyUser WHERE username='admin' AND password='123456' AND state = 1` 修改返回值“ok”,创建map存放查询出的user和flag,转化json字符串,返回在pom.xml里添加json依赖,使用JSON.toJSONString转化对象为json 前台修改接收信息内容,获得登录的user,保存到客户端的 sessionStorage中。 ```js window.sessionStorage.setItem('flag','ok'); ``` 在index.js里创建路由导航 ```js // 挂载路由导航守卫 router.beforeEach((to, from, next) => { // to:将要访问的路径 // from:从哪里访问的路径 // next:之后要做的任务,是一个函数 // next()放行, next('/URL')强制跳转的路径。 if (to.path == '/login') return next();// 访问路径为登录 // 获取flag const flagStr = window.sessionStorage.getItem("flag");// session取值 if (!flagStr) return next('/login');// 没登录去登录 next(); }) // 出现问题的时候使用 const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push(location, onResolve, onReject) { if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) return originalPush.call(this, location).catch(err => err) } ``` #### 3.1.6、安全退出 添加安全退出按钮标签 ```html 安全退出 ``` 添加安全退出方法 ```js logout() { window.sessionStorage.clear(); this.$router.push("/login"); }, ``` ### 3.2.数据创建 略 ## 4、Home页开发 根据主页规划,修改Home。 ![](C:\Users\dz_yk\Desktop\个人运动平台\images\Home主页.png) ### 4.1 引入container布局 ```html Header Aside Main ``` 添加背景 ```css .el-header { background-color: #373d41; } .el-aside { background-color: #333744; } .el-main { background-color: #eaedf1; } ``` 布局充满 ```css .home-container { height: 100%; } ``` ### 4.2 完善Header ```html
运动管理平台
安全退出
``` 样式 ```css .el-header { background-color: #373d41; display: flex; justify-content: space-between;// 左右贴边 padding-left: 0%;// 左边界 align-items: center;// 水平 color: #fff; font-size: 20px; > div { //左侧div加布局 display: flex; align-items: center; span { margin-left: 15px; } } } .logo_img{ width: 55px; height: 55px; } ``` ### 4.3 左侧菜单布局 ```html
|||
``` ### 4.4 访问左侧菜单数据 #### 4.4.1 页面加载请求数据 ```js // 类似onload created() { this.getMenuList(); }, methods里面 // 获取所有的导航菜单 async getMenuList(){ const {data:res} = await this.$http.get("menus"); console.log(res.data); if( res.status != 200) return this.$message.error("操作失败!!!"); this.menuList = res.data; }, ``` #### 4.4.2 定义菜单列表对象 ```js // 左侧菜单 menuList: [], iconsObject: { '100':'iconfont iconguanliyuan', '200':'iconfont iconsport', '101':'iconfont icondenglu', '102':'iconfont iconmima', '103':'iconfont iconsport', '104':'iconfont iconshangpin', '201':'iconfont iconshu', '202':'iconfont iconkaluli', '203':'iconfont iconshiwu', '204':'iconfont icondenglu', }, ``` #### 4.4.3 定义menu后台 bean实体 ```java @Data @AllArgsConstructor @NoArgsConstructor public class SubMenu { private int id; private String title; private String path; } ``` ```java @AllArgsConstructor @NoArgsConstructor public class MainMenu { private int id; private String title; private String path; List list; } ``` 控制器 ```java @Controller public class MenuController { @Autowired private MenuService menuService; @RequestMapping("/menus") @ResponseBody public Object getAllMenus(){ HashMap data = new HashMap<>(); List mainMenus = menuService.getMainMenus(); data.put("data",mainMenus); data.put("status",200); return data; } } ``` mappser层接口类 ```java @Repository public interface MenuDao { public List getMainMenus(); } ``` 映射文件 ```xml ``` #### 4.4.4 消除对不齐的线 ```java .el-aside { background-color: #333744; .el-menu{ border-right: none;// 对其右边框 } } ``` ### 4.5 折叠按钮 添加折叠按钮 ```html
|||
``` 修改按钮样式 ```css .toggle-button{ background-color:#4A5064; font-size: 10px; line-height: 24px; color:#fff; text-align: center; letter-spacing: 0.2em; cursor: pointer;// 显示鼠标指针为:小手 } ``` 定义按键方法 ```js // 切换菜单折叠与展开 toggleCollapase(){ this.isCollapse = !this.isCollapse; }, ``` 添加一些属性 ```html ``` ### 4.6 路由重定向 #### 4.6.1 创建Welcome组价 ```html ``` #### 4.6.2 配置重定向 ```js { path: '/home', component: Home, redirect: '/welcome', children: [ { path:'/welcome', component: Welcome} ], }, ``` #### 4.6.3 侧边栏路由链接 先在侧边栏加入路由属性 ```html ``` 之后修改每一个次级菜单的路径 ```html ``` ## 5、admin组件开发 ### 5.1 创建user组件 在components下新建admin文件夹,在admin文件夹下创建`user.vue` ```html ``` ### 5.2 添加新路由 index.js下home添加新的子组件 ```js { path: '/home', component: Home, redirect: '/welcome', children: [ { path:'/welcome', component: Welcome},{ path:'/user', component: User} ], }, ``` ### 5.3 路径高亮 home组件中添加一个新的属性default-active ```html ``` 创建`连接激活`事件 ```html ``` 创建`连接激活`属性 ```js // 被激活的连接 activePath:'', ``` ```html ``` 创建 `连接激活`方法 ```js saveNavState(activePath){ window.sessionStorage.setItem('activePath',activePath);// 存放点击的二级菜单 this.activePath = activePath;// 给点击的菜单添加高亮 }, ``` 修改create方法 ```js created() { this.getMenuList(); this.activePath = window.sessionStorage.getItem('activePath');// 取出session里的访问路径 }, ``` ![image-20200602152626482](C:\Users\dz_yk\AppData\Roaming\Typora\typora-user-images\image-20200602152626482.png) ## 6、用户列表组件开发 ### 6.1 面包屑导航区 ```html 首页 权限管理 用户列表 ``` `全局样式`表里修改样式 ```css /* 面包屑样式 */ .el-breadcrumb{ margin-bottom: 15px; font-size: 12px; } ``` ### 6.2 卡片视图区 ```html ``` 全局card样式 ```css /* 卡片区域 !important 提高样式级别 */ .el-card{ box-shadow: 0 1px 1px rgba(0, 8, 10, 0.15) !important; } ``` 添加搜索组件并且使用栅格 ```html 间隙 列宽 添加用户 ``` ## 7、用户数据获取 ### 7.1、前台组件 create方法 ```js created() { this.getUserList(); }, ``` 获取用户方法 ```js async getUserList() { // 调用post请求 const { data: res } = await this.$http.get("allUser", { params: this.queryInfo }); this.userlist = res.data; // 将返回数据赋值 this.total = res.numbers; // 总个数 }, ``` 封装查询方法 ```js // 请求数据 queryInfo: { query: "", pageNum: 1, pageSize: 5 }, userlist: [],// 用户列表 total: 0, // 最大数据记录 ``` ### 7.2、用户列表后台 控制层 ```java @RequestMapping("/allUser") public String getUserList(QueryInfo queryInfo){ System.out.println(queryInfo); int numbers = userDao.getUserCounts("%"+queryInfo.getQuery()+"%");// 获取数据总数 int pageStart = (queryInfo.getPageNum()-1)*queryInfo.getPageSize(); List users = userDao.getAllUser("%"+queryInfo.getQuery()+"%",pageStart,queryInfo.getPageSize()); HashMap res = new HashMap<>(); res.put("numbers",numbers); res.put("data",users); System.out.println("总条数:"+numbers); String users_json = JSON.toJSONString(res); return users_json; } ``` dao层 ```java @Repository public interface UserDao { public int getUserByMassage(@Param("username") String username, @Param("password") String password); public List getAllUser(@Param("username") String username,@Param("pageStart") int pageStart, @Param("pageSize") int pageSize); public int getUserCounts(@Param("username") String username); ``` Mapper映射文件 ```xml ``` ### 7.3、用户列表渲染 ```html ``` ## 8、分页组件 ### 8.1、分页组件渲染 表格代码: ```vue ``` ### 8.2、相关方法 ```java return { // 请求数据, pageNum: 1, size:5, userlist: [], // 用户列表 total: 0, // 最大数据记录 addDialogVisible: false, // 对话框显示 // 添加用户表单项 addForm: { username: "", password: "", email: "", }, // 控制修改用户对话框显示/隐藏 editDialogVisible: false, // 修改用户信息 editForm: {}, // 验证规则 addFormRules: { username: [ { required: true, message: "请输入用户名", trigger: "blur" }, { min: 2, max: 8, message: "长度在 2 到 8 个字符", trigger: "blur" }, ], password: [ { required: true, message: "请输入密码", trigger: "blur" }, { min: 6, max: 8, message: "长度在 6 到 8 个字符", trigger: "blur" }, ], email: [ { required: true, message: "请输入邮箱", trigger: "blur" }, { min: 5, max: 15, message: "请输入正确邮箱地址", trigger: "blur" }, ], }, // 修改用户表单验证规则 editFormRules: { password: [ { required: true, message: "请输入密码", trigger: "blur" }, { min: 6, max: 8, message: "长度在 6 到 8 个字符", trigger: "blur" }, ], email: [ { required: true, message: "请输入邮箱", trigger: "blur" }, { min: 5, max: 15, message: "请输入正确邮箱地址", trigger: "blur" }, ], }, }; }, created() { this.getUserList(); }, methods: { async getUserList() { //调用post请求 const { data: res } = await this.$http.post("user/queryAll/" +this.pageNum+'/'+this.size); this.userlist = res.userList; // 将返回数据赋值 this.total = res.total; // 总个数 }, // 监听pageSize改变的事件 handleSizeChange(newSize) { this.size=newSize; this.getUserList(); // 数据发生改变重新申请数据 }, // 监听pageNum改变的事件 handleCurrentChange(newSize) { // 调用post请求 this.pageNum=newSize; // 将返回数据赋值 this.getUserList(); // 数据发生改变重新申请数据 }, ``` ## 9、用户状态修改 ### 9.1、绑定change方法 ```html ``` ### 9.2、创建changeState方法 ```java // 修改用户状态 async userStateChanged(userinfo) { const { data: res } = await this.$http.put( `userState?id=${userinfo.id}&state=${userinfo.state}` ); if (res != "success") { userinfo.state = !userinfo.state; return this.$message.error("操作失败!!!"); } this.$message.success("操作成功!!!"); }, ``` ### 9.3、修改状态后台 #### dao层编写接口 ```java @Repository public interface UserDao { public int updateState(Integer id, Boolean state); } ``` #### dao的映射文件 ```xml UPDATE easyuser SET state = #{state} WHERE id = #{id} ``` #### controller层编写 ```java @RequestMapping("/userState") public String updateUserState(@RequestParam("id") Integer id, @RequestParam("state") Boolean state){ int i = userDao.updateState(id, state); String str = i >0?"success":"error"; return str; } ``` ## 10、添加功能实现 ### 10.1、mapper接口方法 ```java public User findUserNameAndPaw(String username,String password); public List findAll(); public User findUserName(String username); public User findById(Integer id); public int addUser(User user); public int editUser(User user); public int deleteUser(Integer id); public int updateState(Integer id, Boolean state); ``` ### 10.2、mapper接口sql语句实现 ```xml UPDATE easyuser SET state = #{state} WHERE id = #{id} INSERT INTO easyuser (username,password,email,role,state) VALUE (#{username},#{password},#{email},#{role},1) UPDATE easyuser SET username = #{username} , password = #{password} , email = #{email} WHERE id = #{id} DELETE FROM easyuser WHERE id = #{id} ``` ### 10.3service接口实现 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User findUserNameAndPaw(String username, String password) { return userMapper.findUserNameAndPaw(username,password); } @Override public List findAll() { return userMapper.findAll(); } public Map queryAll(Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum,pageSize); List list = userMapper.findAll(); PageInfo pageInfo = new PageInfo(list); Map map = new HashMap<>(); //查询数据 map.put("userList",pageInfo.getList()); //查询总条数 map.put("total",pageInfo.getTotal()); return map; } @Override public User findUserName(String username) { return userMapper.findUserName(username); } @Override public User findById(Integer id) { return userMapper.findById(id); } @Override public int addUser(User user) { return userMapper.addUser(user); } @Override public int editUser(User user) { return userMapper.editUser(user); } @Override public int deleteUser(Integer id) { return userMapper.deleteUser(id); } @Override public int updateState(Integer id, Boolean state) { return userMapper.updateState(id,state); } } ``` ### 10.4controller控制层 ```java @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/findAll") @ResponseBody public List findAll(){ return userService.findAll(); } @RequestMapping("/queryAll") @ResponseBody public Map queryAll(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize){ return userService.queryAll(pageNum,pageSize); } @RequestMapping("/updateState") @ResponseBody public String updateState(@RequestParam("id") Integer id,@RequestParam("state") boolean state){ int n = userService.updateState(id,state); if(n>0){ return "success"; } return "error"; } @RequestMapping("/addUser") @ResponseBody public String addUser(@RequestBody User user){ int n = userService.addUser(user); if(n>0){ return "success"; } return "error"; } } ``` ### 10.5前端代码修改 (1)添加 ```vue // 添加用户表单项 addForm: { username: "", password: "", email: "", role: "" }, 取 消 确 定 ``` ```js // 添加用户 addUser() { this.$refs.addFormRef.validate(async (valid) => { if (!valid) return; // 发起请求 const { data: res } = await this.$http.post( "user/addUser", this.addForm ); if (res != "success") { return this.$message.error("添加失败!!!"); } this.$message.success("添加成功!!!"); //隐藏 this.addDialogVisible = false; this.pageNum = 1; // 将返回数据赋值 this.getUserList(); }); }, ``` (2)删除 ```vue ``` ```js // 删除按钮 async deleteUser(id) { // 弹框 const confirmResult = await this.$confirm( "此操作将永久删除该用户, 是否继续?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", } ).catch((err) => err); // 成功删除为confirm 取消为 cancel if (confirmResult != "confirm") { return this.$message.info("已取消删除"); } const { data: res } = await this.$http.delete("user/deleteUser?id=" + id); if (res != "success") { return this.$message.error("删除失败!!!"); } this.$message.success("删除成功!!!"); this.getUserList(); }, ``` (3)修改 第一步: 数据回显: ```java @RequestMapping("/getUpdate") @ResponseBody public User getUpdate(@RequestParam("id") Integer id){ return userService.findById(id); } ``` ```vue 修改 ``` 提交修改数据: ```java @RequestMapping("/editUser") @ResponseBody public String editUser(@RequestBody User user){ int n = userService.editUser(user); if(n>0){ return "success"; } return "error"; } ``` ```js // 确认修改 editUserInfo() { this.$refs.editFormRef.validate(async (valid) => { if (!valid) return; // 发起请求 const { data: res } = await this.$http.put("user/editUser", this.editForm); if (res != "success") return this.$message.error("修改失败!!!"); this.$message.success("修改成功!!!"); //隐藏 this.editDialogVisible = false; this.getUserList(); }); }, ```