SpringBoot3+vue3实现增删改查,分页查询,批量删除
安装axios封装前后端对接数据工具
其中-s参数的作用是减少npm的输出信息,使其保持静默模式。也就是说,npm在这种模式下不会显示详细的安装过程,只会显示错误信息。所以用户可能没有看到任何输出,但实际上安装可能已经成功了。
检查是否成功:
简单测试axios
1 2 3 axios.get ("http://localhost:9999/admin/selectAll" ).then (res => { console .log (res) })
跨域处理
在Springboot里面设置统一的跨域处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package com.yjy.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import org.springframework.web.filter.CorsFilter;@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter () { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource (); CorsConfiguration corsConfiguration = new CorsConfiguration (); corsConfiguration.addAllowedOrigin("*" ); corsConfiguration.addAllowedHeader("*" ); corsConfiguration.addAllowedMethod("*" ); source.registerCorsConfiguration("/**" ,corsConfiguration); return new CorsFilter (source); } }
封装统一的请求工具request.js
在src下新建一个文件夹utils,然后新建一个文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 import axios from "axios" ;import {ElMessage } from "element-plus" ;const request = axios.create ({ baseURL : 'http://localhost:9999' , timeout : 30000 }) request.interceptors .request .use (config => { config.headers ['Content-Type' ]='application/json;charset=utf-8' ; return config },error => { return Promise .reject (error) }); request.interceptors .response .use ( response => { let res = response.data ; if (typeof res === 'string' ){ res = res?JSON .parse (res):res } return res; }, error => { if (error.response .status === 404 ){ ElMessage .error ("未找到请求接口" ) }else if (error.response .status ===500 ) { ElMessage .error ("系统异常,请查看后端控制台报错" ) }else { console .error (error.message ) } return Promise .reject (error) } ) export default request
使用request工具发起一次请求
1 2 3 4 5 6 7 request.get('/admin/selectAll').then(res=>{ if(res.code==='200'){ console.log(res); }else{ ElMessage.error(res,msg) } })
分页查询
分页对象
total: 总的个数
list: 返回的数据数组
pageNum: 当前的页码
pageSize: 每页展示的个数
使用PageHelper 插件
在pom.xml里添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 <dependency > <groupId > com.github.pagehelper</groupId > <artifactId > pagehelper-spring-starter</artifactId > <version > 1.4.6</version > <exclusions > <exclusion > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > </exclusion > </exclusions > </dependency >
AdminController.java
1 2 3 4 5 6 7 8 9 10 11 @GetMapping("/selectPage") public Result selectPage (@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { adminService.selectPage(pageNum,pageSize); return Result.success(); }
AdminService.java
1 2 3 4 5 6 public PageInfo<Admin> selectPage (Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum,pageSize); List<Admin> admins = adminMapper.selectAll(); return PageInfo.of(admins); }
修改前端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <!-- 菜单区域开始 --> <div style="width: 240px; box-shadow: 0 0 8px rgba(0,0,0,.12)"> <!-- :default-openeds="['1']" : 默认展开 --> <el-menu router :default-active="router.currentRoute.value.path" style="min-height: calc(100vh - 60px)"> <el-menu-item index="/manager/home"> <el-icon><House /></el-icon> <span>Home</span> </el-menu-item> <el-sub-menu index="1"> <template #title> <el-icon><location /></el-icon> <span>User Management</span> </template> <el-menu-item index="/manager/admin">Administrator information </el-menu-item> </el-sub-menu> </el-menu> </div> <!-- 菜单区域结束 -->
然后将Home.vue改为Admin.vue,然后再去创建一个新的Home.vue
1 2 3 4 5 <template> <div> <div class="card">泥嚎!欢迎使用本系统!</div> </div> </template>
修改index.js
1 2 3 4 5 6 7 8 9 10 11 12 routes : [ {path : '/' ,redirect : '/manager/home' }, {path : '/manager' , component : import ('../views/Manager.vue' ), children : [ {path : 'home' , component : import ('../views/Home.vue' ),}, {path : 'admin' , component : import ('../views/Admin.vue' ),}, ] }, {path : '/notFound' , component : import ('../views/404.vue' ),}, {path : '/:pathMatch(.*)' ,redirect : '/notFound' } ],
然后可以把About.vue删除了
package.json中有一个"vite-plugin-vue-devtools"可以卸载掉 因为没啥用
1 npm uninstall vite-plugin-vue-devtools
删除vite.config.js中的这一行
还有plugins中vue()下的vueDevTools()
这样能够让速度速度变快
后端返回的分页对象
排查问题: 页面数据少了,不展示怎么办?
看网络请求的数据对不对,发现传输的数据没有name字段
修改Admin.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 <template> <div> <div class="card" style="margin-bottom: 5px"> <el-input style="width: 240px;margin-right: 5px;" v-model="input" placeholder="请输入名称查询" :prefix-icon="Search"></el-input> <el-button type="primary">查询</el-button> </div> <div class="card" style="margin-bottom: 5px"> <el-button type="danger">批量删除</el-button> <el-button type="primary">新 增</el-button> <el-button type="success">批量导入</el-button> <el-button type="info">批量导出</el-button> </div> <div class="card" style="margin-bottom: 5px"> <el-table :data="data.tableData" style="width: 100%" :header-cell-style="{fontWeight: 'bold',color: '#333',backgroundColor: '#c902f6'}"> <el-table-column prop="username" label="账号"/> <el-table-column prop="name" label="名称" /> <el-table-column prop="phone" label="电话" /> <el-table-column prop="email" label="邮箱" /> </el-table> </div> <!-- 分页--> <div class="card"> <el-pagination v-model:current-page="data.pageNum" :page-size="data.pageSize" layout="total, prev, pager, next" :total="data.total" @current-change="load" /> </div> </div> </template> <script setup> import {reactive} from "vue"; import {Search} from "@element-plus/icons-vue"; import axios from "axios"; import request from "@/utils/request.js"; import {ElMessage} from "element-plus"; const data = reactive({ name: null, pageNum: 1, pageSize: 5, total: 0, tableData: [] }) const load = () => { request.get('/admin/selectPage',{ params: { pageNum: data.pageNum, pageSize: data.pageSize } }).then(res=>{ // console.log(res.data) data.tableData = res.data.list; data.total = res.data.total; }) } load() </script>
完整的分页查询的请求方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 <template> <div> <div class="card" style="margin-bottom: 5px" > <el-input style="width: 240px;margin-right: 5px;" v-model="data.name" placeholder="请输入名称查询" :prefix-icon="Search" ></el-input> <el-button type="primary" >查询</el-button> </div> <div class="card" style="margin-bottom: 5px" > <el-button type="danger" >批量删除</el-button> <el-button type="primary" >新 增</el-button> <el-button type="success" >批量导入</el-button> <el-button type="info" >批量导出</el-button> </div> <div class="card" style="margin-bottom: 5px" > <el-table :data="data.tableData" style="width: 100%" :header-cell-style="{fontWeight: 'bold',color: '#333',backgroundColor: '#c902f6'}" > <el-table-column prop="username" label="账号" /> <el-table-column prop="name" label="名称" /> <el-table-column prop="phone" label="电话" /> <el-table-column prop="email" label="邮箱" /> </el-table> </div> <!-- 分页--> <div class="card" > <el-pagination v-model:current-page="data.pageNum" v-model:page-size="data.pageSize" :page-size="data.pageSize" layout="total,sizes, prev, pager, next,jumper" :page-sizes="[5,10,20]" :total="data.total" @current -change="load" @size -change="load" /> </div> </div> </template> <script setup> import {reactive} from "vue" ;import {Search} from "@element-plus/icons-vue" ;import axios from "axios" ;import request from "@/utils/request.js" ;import {ElMessage} from "element-plus" ;const data = reactive({ name: null , pageNum: 1 , pageSize: 5 , total: 0 , tableData: [] }) const load = () => { request.get('/admin/selectPage' ,{ params: { pageNum: data.pageNum, pageSize: data.pageSize } }).then(res=>{ if (res.code === '200' ){ data.tableData = res.data.list; data.total = res.data.total; }else { ElMessage.error(res.msg); } }) } load() </script>
本节要做到下面的效果:
分页条件模糊查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.yjy.mapper.AdminMapper" > <select id ="selectAll" resultType ="com.yjy.entity.Admin" > SELECT * FROM `admin` <where > <if test ="name != null and name != ''" > name LIKE CONCAT('%', #{name}, '%') </if > <if test ="username != null and username != ''" > and username LIKE CONCAT('%', #{username}, '%') </if > </where > ORDER BY id DESC </select > </mapper >
vue的调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 const data = reactive({ username: null, name: null, pageNum: 1, pageSize: 5, total: 0, tableData: [], }) const load = () => { request.get('/admin/selectPage',{ params: { pageNum: data.pageNum, pageSize: data.pageSize, name: data.name, username: data.username } }).then(res=>{ if(res.code === '200'){ data.tableData = res.data.list; data.total = res.data.total; }else{ ElMessage.error(res.msg); } }) } load() const reset = () => { data.name = null load() }
本节课代码案例:
Admin.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 <template> <div> <div class="card" style="margin-bottom: 5px"> <!-- 加上clearable这个属性可以快速清除也就是那个叉叉顺便刷新一下 v-model="data.name" 将输入的文字显示到输入框内--> <el-input clearable @clear="load" style="width: 240px;margin-right: 5px;" v-model="data.name" placeholder="请输入名称查询" :prefix-icon="Search"></el-input> <el-input clearable @clear="load" style="width: 240px;margin-right: 5px;" v-model="data.username" placeholder="请输入账号查询" :prefix-icon="Search"></el-input> <el-button type="primary" @click="load">查 询</el-button> <el-button @click="reset">重 置</el-button> </div> <div class="card" style="margin-bottom: 5px"> <el-button type="danger">批量删除</el-button> <el-button type="primary">新 增</el-button> <el-button type="success">批量导入</el-button> <el-button type="info">批量导出</el-button> </div> <div class="card" style="margin-bottom: 5px"> <el-table :data="data.tableData" style="width: 100%" :header-cell-style="{fontWeight: 'bold',color: '#333',backgroundColor: '#c902f6'}"> <el-table-column prop="username" label="账号"/> <el-table-column prop="name" label="名称" /> <el-table-column prop="phone" label="电话" /> <el-table-column prop="email" label="邮箱" /> </el-table> </div> <!-- 分页--> <div class="card"> <el-pagination v-model:current-page="data.pageNum" v-model:page-size="data.pageSize" :page-size="data.pageSize" layout="total,sizes, prev, pager, next,jumper" :page-sizes="[5,10,20]" :total="data.total" @current-change="load" @size-change="load" /> </div> </div> </template> <script setup> import {reactive} from "vue"; import {Search} from "@element-plus/icons-vue"; import axios from "axios"; import request from "@/utils/request.js"; import {ElMessage} from "element-plus"; const data = reactive({ username: null, name: null, pageNum: 1, pageSize: 5, total: 0, tableData: [], }) const load = () => { request.get('/admin/selectPage',{ params: { pageNum: data.pageNum, pageSize: data.pageSize, name: data.name, username: data.username } }).then(res=>{ if(res.code === '200'){ data.tableData = res.data.list; data.total = res.data.total; }else{ ElMessage.error(res.msg); } }) } load() const reset = () => { data.name = null load() } </script>
AdminController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package com.yjy.controller;import com.github.pagehelper.PageInfo;import com.yjy.common.Result;import com.yjy.entity.Admin;import com.yjy.service.AdminService;import jakarta.annotation.Resource;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController @RequestMapping("/admin") public class AdminController { @Resource AdminService adminService; @GetMapping("/selectAll") public Result selectAll () { List<Admin> admins = adminService.selectAll(); return Result.success(admins); } @GetMapping("/selectPage") public Result selectPage (@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, Admin admin) { PageInfo<Admin> adminPageInfo = adminService.selectPage(pageNum, pageSize,admin); return Result.success(adminPageInfo); } }
adminService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.yjy.service;import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import com.yjy.entity.Admin;import com.yjy.exception.CustomerException;import com.yjy.mapper.AdminMapper;import jakarta.annotation.Resource;import org.springframework.stereotype.Service;import java.util.List;@Service public class AdminService { @Resource AdminMapper adminMapper; public String admin (String name) { if ("admin" .equals(name)){ return "admin" ; }else { throw new CustomerException ("账号错误!" ); } } public List<Admin> selectAll () { return adminMapper.selectAll(null ); } public PageInfo<Admin> selectPage (Integer pageNum, Integer pageSize,Admin admin) { PageHelper.startPage(pageNum,pageSize); List<Admin> admins = adminMapper.selectAll(admin); return PageInfo.of(admins); } }
ctrl+Alt+o可以删除无效的导包
解决方案 :
router/index,js
1 2 3 4 5 6 7 8 9 10 11 routes : [ {path : '/' ,redirect : '/manager/home' }, {path : '/manager' , component :() => import ('../views/Manager.vue' ), children : [ {path : 'home' ,meta :{name :'主页' }, component :() => import ('../views/Home.vue' ),}, {path : 'admin' ,meta :{name :'管理员信息' }, component :() => import ('../views/Admin.vue' ),}, ] }, {path : '/notFound' , component : import ('../views/404.vue' ),}, {path : '/:pathMatch(.*)' ,redirect : '/notFound' }
新增数据
1.在新增的按钮上加上点击事件
2.定义弹窗和表单的页面代码
3.点击触发弹窗打开 (form 对象清空)
4.弹窗里面的内容就是表单
5.表单做一下数据绑定以及表单验证
6.后台要有对应新增的接口来接受数据
7.新增的接口负责把数据插入到数据库里面
8.表达输入数据后点击确认按钮,把表单的数据传给后台接口
9.在新增之后再次加载表格的数据,关闭弹窗
Dialog弹窗
1 2 3 4 5 6 7 8 9 10 11 <el-dialog v-model="data.formVisible" title="管理员信息" width="500"> <template #footer> <div class="dialog-footer"> <el-button @click="data.formVisible = false">Cancel</el-button> <el-button type="primary" @click="add"> Confirm </el-button> </div> </template> </el-dialog>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <el-form :model="data.form" label-width="80px" style="padding: 20px 30px 10px 0"> <el-form-item label="账号"> <el-input v-model="data.form.username" autocomplete="off" /> </el-form-item> <el-form-item label="名称"> <el-input v-model="data.form.name" autocomplete="off" /> </el-form-item> <el-form-item label="电话"> <el-input v-model="data.form.phone" autocomplete="off" /> </el-form-item> <el-form-item label="邮箱"> <el-input v-model="data.form.email" autocomplete="off" /> </el-form-item> </el-form>
表单验证
1.在表单el-form上有三个必须的属性
1 ref = "formRef" :model="data.form" :rules="data.rules"
2.在el-form-item 上写上表单项prop
1 <el-form -item prop="username"
3.在rules里面定义验证的规则
4.定义formRef对象,作为表单的引用
5.通过formRef对象进行表单验证
destroy-on-close属性可以重置dialog
1 2 3 4 5 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8 .26 </version> </dependency>
admin 的新增流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public void add (Admin admin) { Admin dbAdmin = adminMapper.selectByUsername(admin.getUsername()); if (dbAdmin!=null ){ throw new CustomerException ("账号重复" ); } if (StrUtil.isBlank(admin.getPassword())) { admin.setPassword("admin" ); } adminMapper.insert(admin); }
新增数据
1.在编辑的按钮上加上点击事件
2.定义弹窗和表单的页面代码
3.点击触发弹窗打开 (将行对象的数据row深度拷贝给form 对象)
4.表单做一下数据绑定以及表单验证
5.后台要有对应修改的接口来接受数据
6.修改的接口负责把数据插入到数据库里面
7.表达输入数据后点击确认按钮,把表单的数据传给后台接口
8.在修改成功之后再次加载表格的数据,关闭弹窗
405 错误表示你请求的方法类型跟后端定义的方法类型不一致
比如前端是put请求,后台是post接口
兼容新增和修改
1 2 3 const save = ( ) => { data.form .id ? update ():add () }
删除数据
MessageBox
单个删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const del = (id )=>{ ElMessageBox .confirm ('删除后无法恢复,您确认删除吗?' ,'删除确认' ,{ type :"warning" }).then (res => { request.delete ('/admin/delete/' +id).then (res => { if (res.code === '200' ){ ElMessage .success ('删除成功' ) load () }else { ElMessage .error (res.msg ); } }) }).catch (err => { }) }
批量删除
table的多选事件
1 @selection-change="handleSelectionChange"
在 Element Plus 的 el-table 中,要启用多选功能,除了添加 @selection-change 事件外,还需要在表格列中显式添加 type="selection" 的列 。以下是完整的实现步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <el-table :data="data.tableData" style="width: 100%" @selection-change="handleSelectionChange" :header-cell-style="{fontWeight: 'bold', color: '#333', backgroundColor: '#c902f6'}" > <!-- 多选列 --> <el-table-column type ="selection" width ="55" <!-- 可根据需要调整宽度 -- > ></el-table-column > <!-- 其他列 --> <el-table-column prop ="id" label ="ID" > </el-table-column > <el-table-column prop ="name" label ="名称" > </el-table-column > </el-table>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const deleteBatch = ( ) =>{ if (data.rows .length === 0 ){ ElMessage .warning ('请选择数据' ) return } ElMessageBox .confirm ('删除后无法恢复,您确认删除吗?' ,'删除确认' ,{ type :"warning" }).then (res => { request.delete ('/admin/deleteBatch' ,{data : data.rows }).then (res => { if (res.code === '200' ){ ElMessage .success ('批量删除成功' ) load () }else { ElMessage .error (res.msg ); } }) }).catch (err => { }) }
完整代码:
后端就是简单的crud
直接给前端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 <template> <div > <div class ="card" style ="margin-bottom: 5px" > <el-input clearable @clear ="load" style ="width: 240px;margin-right: 5px;" v-model ="data.name" placeholder ="请输入名称查询" :prefix-icon ="Search" > </el-input > <el-input clearable @clear ="load" style ="width: 240px;margin-right: 5px;" v-model ="data.username" placeholder ="请输入账号查询" :prefix-icon ="Search" > </el-input > <el-button type ="primary" @click ="load" > 查 询</el-button > <el-button @click ="reset" > 重 置</el-button > </div > <div class ="card" style ="margin-bottom: 5px" > <el-button type ="primary" @click ="handleAdd" > 新 增</el-button > <el-button type ="danger" @click ="deleteBatch" > 批量删除</el-button > <el-button type ="success" > 批量导入</el-button > <el-button type ="info" > 批量导出</el-button > </div > <div class ="card" style ="margin-bottom: 5px" > <el-table :data ="data.tableData" style ="width: 100%" @selection-change ="handleSelectionChange" :header-cell-style ="{fontWeight: 'bold',color: '#333',backgroundColor: '#c902f6'}" > <el-table-column type ="selection" width ="55" > </el-table-column > <el-table-column prop ="username" label ="账号" /> <el-table-column prop ="name" label ="名称" /> <el-table-column prop ="phone" label ="电话" /> <el-table-column prop ="email" label ="邮箱" /> <el-table-column label ="操作" width ="100" > <template #default ="scope" > <el-button type ="primary" icon ="Edit" circle @click ="handleEdit(scope.row)" > </el-button > <el-button type ="danger" icon ="Delete" circle @click ="del(scope.row.id)" > </el-button > </template > </el-table-column > </el-table > </div > <div class ="card" > <el-pagination v-model:current-page ="data.pageNum" v-model:page-size ="data.pageSize" :page-size ="data.pageSize" layout ="total,sizes, prev, pager, next,jumper" :page-sizes ="[5,10,20]" :total ="data.total" @current-change ="load" @size-change ="load" /> </div > <el-dialog v-model ="data.formVisible" title ="管理员信息" width ="30%" destroy-on-close > <el-form ref ="formRef" :model ="data.form" :rules ="data.rules" label-width ="80px" style ="padding: 20px 30px 10px 0" > <el-form-item prop ="username" label ="账号" > <el-input v-model ="data.form.username" autocomplete ="off" /> </el-form-item > <el-form-item prop ="name" label ="名称" > <el-input v-model ="data.form.name" autocomplete ="off" /> </el-form-item > <el-form-item prop ="name" label ="电话" > <el-input v-model ="data.form.phone" autocomplete ="off" /> </el-form-item > <el-form-item prop ="name" label ="邮箱" > <el-input v-model ="data.form.email" autocomplete ="off" /> </el-form-item > </el-form > <template #footer > <div class ="dialog-footer" > <el-button @click ="data.formVisible = false" > Cancel</el-button > <el-button type ="primary" @click ="save()" > Confirm </el-button > </div > </template > </el-dialog > </div > </template> <script setup > import {reactive, ref} from "vue" ;import {Search } from "@element-plus/icons-vue" ;import axios from "axios" ;import request from "@/utils/request.js" ;import {ElMessage , ElMessageBox } from "element-plus" ;const data = reactive ({ username : null , name : null , pageNum : 1 , pageSize : 5 , total : 0 , tableData : [], formVisible : false , form : {}, rules : { username : [ { required :true ,message : '请填写账号' ,trigger : 'blur' } ], name : [ { required :true ,message : '请填写名称' ,trigger : 'blur' } ], phone : [ { required :true ,message : '请填写手机' ,trigger : 'blur' } ], email : [ { required :true ,message : '请填写邮箱' ,trigger : 'blur' } ] }, rows : [] }) const formRef = ref ()const load = ( ) => { request.get ('/admin/selectPage' ,{ params : { pageNum : data.pageNum , pageSize : data.pageSize , name : data.name , username : data.username } }).then (res => { if (res.code === '200' ){ data.tableData = res.data .list ; data.total = res.data .total ; }else { ElMessage .error (res.msg ); } }) } load ()const reset = ( ) => { data.name = null load () } const handleAdd = ( ) => { data.formVisible = true data.form = {} } const add = ( ) => { formRef.value .validate ((valid ) => { if (valid){ request.post ('/admin/add' ,data.form ).then (res => { if (res.code === '200' ){ data.formVisible = false ElMessage .success ('新增成功' ) load () }else { ElMessage .error (res.msg ); } }) } }) } const handleEdit = (row ) => { data.form = JSON .parse (JSON .stringify (row)) data.formVisible = true } const update = ( ) => { formRef.value .validate ((valid ) => { if (valid){ request.put ('/admin/update' ,data.form ).then (res => { if (res.code === '200' ){ data.formVisible = false ElMessage .success ('修改成功' ) load () }else { ElMessage .error (res.msg ); } }) } }) } const save = ( ) => { data.form .id ? update ():add () } const del = (id )=>{ ElMessageBox .confirm ('删除后无法恢复,您确认删除吗?' ,'删除确认' ,{ type :"warning" }).then (res => { request.delete ('/admin/delete/' +id).then (res => { if (res.code === '200' ){ ElMessage .success ('删除成功' ) load () }else { ElMessage .error (res.msg ); } }) }).catch (err => { }) } const handleSelectionChange = (rows ) => { console .log (rows) data.rows = rows } const deleteBatch = ( ) =>{ if (data.rows .length === 0 ){ ElMessage .warning ('请选择数据' ) return } ElMessageBox .confirm ('删除后无法恢复,您确认删除吗?' ,'删除确认' ,{ type :"warning" }).then (res => { request.delete ('/admin/deleteBatch' ,{data : data.rows }).then (res => { if (res.code === '200' ){ ElMessage .success ('批量删除成功' ) load () }else { ElMessage .error (res.msg ); } }) }).catch (err => { }) } </script >
SpringBoot3+vue3实现增删改查,分页查询,批量删除