1、Vue3.0前端代码
1.1、前端代码书写
注:此页面设计el-table、el-pagination、el-dialog、el-form及一些其他的组件,可参考ElementPlus官网(一个 Vue 3 UI 框架 | Element Plus)文档详细使用。
<template>
<div style="margin-bottom: 15px">
<el-input v-model="params.name" style="width: 240px" placeholder="请输入用户名" />
<el-input v-model="params.phone" style="width: 240px; margin-left: 5px" placeholder="请输入手机号" />
<el-button type="warning" style="margin-left: 10px" @click="findBySearch">查询</el-button>
<el-button type="primary" style="margin-left: 10px" @click="resetInput">清空</el-button>
<el-button type="primary" style="margin-left: 10px" @click="addUserInfo">新增</el-button>
</div>
<div>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="姓名" />
<el-table-column prop="sex" label="性别" />
<el-table-column prop="age" label="年龄" />
<el-table-column prop="phone" label="手机号" />
<el-table-column label="操作">
<template #default="scope">
<el-button @click="editUserInfo(scope.row)" type="primary">编辑</el-button>
<el-popconfirm title="你确定要删除吗?" @confirm="userInfoDelete(scope.row)" confirm-button-text="确定"
cancel-button-text="取消" width="300px">
<template #reference>
<el-button type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<div class="demo-pagination-block">
<el-pagination v-model:current-page="params.currentPage" v-model:page-size="params.pageSize"
:page-sizes="[5, 10, 15, 20]" layout="total, sizes, prev, pager, next, jumper" :total="total"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
<div>
<!-- 对话框 -->
<el-dialog v-model="dialogVisible" title="请填写用户信息" width="500">
<el-form ref="addFormRef" style="max-width: 600px" :model="addForm" :rules="rules" label-width="120px"
class="demo-ruleForm" status-icon>
<el-form-item label="姓名" prop="name">
<el-input v-model="addForm.name" />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio v-model="addForm.sex" label="男">男</el-radio>
<el-radio v-model="addForm.sex" label="女">女</el-radio>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model="addForm.age" />
</el-form-item>
<el-form-item label="手机" prop="phone">
<el-input v-model="addForm.phone" />
</el-form-item>
<el-form-item label="角色" prop="typeId">
<el-select v-model="addForm.role" placeholder="请选择角色类型" style="width: 90%;">
<el-option label="教师" value="teacher"></el-option>
<el-option label="用户" value="user"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmAdd()">
确定
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { onMounted, ref, reactive } from "vue";
import { ElMessage } from 'element-plus'
import request from "../../utils/request";
const params = ref({
name: "",
phone: "",
currentPage: 1,
pageSize: 5,
});
const tableData = ref([]);
onMounted(() => {
findBySearch();
});
const findBySearch = async () => {
var res = await request.get(`http://localhost:8080/user/search`, { params: params.value });
// console.log(res);
tableData.value = res.data.list;
total.value = res.data.total;
};
const resetInput = () => {
params.value.name = "";
params.value.phone = "";
findBySearch()
};
const total = ref(0);
const handleSizeChange = async (pageSize) => {
params.value.pageSize = pageSize;
await findBySearch();
};
const handleCurrentChange = async (currentPage) => {
params.value.currentPage = currentPage;
await findBySearch();
};
const dialogVisible = ref(false)
const addUserInfo = () => {
addForm.name = ""
addForm.sex = "男"
addForm.age = ""
addForm.phone = ""
addForm.role = ""
dialogVisible.value = true
}
const addFormRef = ref()
const addForm = reactive({
name: "",
sex: "男",
age: "",
phone: "",
role: ''
})
const rules = reactive({
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
],
sex: [
{ required: true, message: '请选择性别', trigger: 'blur' },
],
age: [
{ required: true, message: '请输入年龄大小', trigger: 'blur' },
],
phone: [
{ required: true, message: '请填写一下手机号', trigger: 'blur' },
]
})
const confirmAdd = () => {
addFormRef.value.validate(async (valid) => {
if (valid) {
dialogVisible.value = false
if (addForm.id) {
await request.post(`更新接口`, addForm)
ElMessage({
message: '更新成功,请稍后',
type: 'success',
})
} else {
let res = await request.post(`新增接口`, addForm)
console.log(res);
if (res.code === "200") {
ElMessage({
message: "添加成功,请稍后",
type: 'success',
})
} else {
ElMessage.error(res.message)
}
}
await findBySearch()
}
})
}
// 编辑
const editUserInfo = (rowObj) => {
addForm.name = rowObj.name
addForm.sex = rowObj.sex
addForm.age = rowObj.age
addForm.phone = rowObj.phone
addForm.id = rowObj.id
addForm.role = rowObj.role
dialogVisible.value = true
}
const userInfoDelete = async ({ id }) => {
await request.delete(`删除接口`)
await findBySearch()
}
</script>
<style lang="scss" scoped>
.demo-pagination-block {
margin-top: 15px;
margin-right: 10px;
}
.el-pagination {
margin-left: 30%;
}
</style>
1.2、axios封装使用
import axios from 'axios'
const request=axios.create({
baseURL: '设置地址',
timeout: 5000
})
// 发出请求之前
request.interceptors.request.use(function (config) {
// 请求头设置
config.headers['Content-Type']='application/json;charset=utf-8'
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// 处理then和catch之前
request.interceptors.response.use(function (response) {
// 统一判断是否存在token,存储
let res=response.data
if(typeof res==='string'){
res=res?JSON.parse(res):res
}
return res;
}, function (error) {
console.log('error:'+error);
return Promise.reject(error);
});
export default request
注:github上有关于axios的详细文档,可作为自己书写的代码的参考文档(https://github.com/axios/axios)
2、SpringBoot3.0后端代码
2.1、导入所需依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- mysql依赖 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- get、set依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
<!-- mybatis分页查询插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
<!-- 综合一些简单的查询语句,可直接使用 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.5</version>
</dependency>
2.2、application.yml
server:
port: 8080
spring:
main:
allow-circular-references: true # 解决循环依赖问题
application:
name: demo
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/back_management
username: root
password: 123456
mybatis: # mybatis配置(配置位置)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.example.demo.entity
configuration:
map-underscore-to-camel-case: true
2.3、定义统一的数据返回类型
@Data
public class Result {
private static final String SUCCESS="200";
private static final String ERROR="404";
private String code;
private String message;
private Object data;
public static Result success(){
Result result = new Result();
result.setCode(SUCCESS);
return result;
}
public static Result success(Object data){
Result result = new Result();
result.setCode(SUCCESS);
result.setData(data);
return result;
}
public static Result error(String message){
Result result = new Result();
result.setCode(ERROR);
result.setMessage(message);
return result;
}
}
2.4、UserController类
@CrossOrigin // 简单的解决跨域问题
@RestController //接口的入口
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@GetMapping("/search")
public Result searchUserInfo(User user){
PageInfo<User> info=userService.searchUserInfo(user);
return Result.success(info);
}
}
注:可单独的书写跨域配置配置类(可参考:在 Spring 应用中处理 CORS 跨域 - spring 中文网)
2.5、UserService接口类
public interface UserService {
PageInfo<User> searchUserInfo(User user);
}
2.6、UserServiceImpl接口实现类
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
public PageInfo<User> searchUserInfo(User admin) {
// 开启分页查询
PageHelper.startPage(admin.getCurrentPage(), admin.getPageSize());
// 接下来的查询会按照当前开启的分页设置来进行查询
List<User> list=userMapper.searchUserInfo(admin);
return PageInfo.of(list);
}
}
2.7、UserMapper类
@Repository
public interface UserMapper extends Mapper<User> {
List<User> searchUserInfo(@Param("user") User user);
}
2.8、UserMapper.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.dao.UserMapper">
<select id="searchUserInfo" resultType="com.example.demo.entity.User">
select * from admin
<where>
<if test="user != null and user.name != null and user.name != ''">
and name like concat('%',#{user.name},'%')
</if>
<if test="user != null and user.phone != null and user.phone != ''">
and phone like concat('%',#{user.phone},'%')
</if>
</where>
</select>
</mapper>
2.9、User实体类
@Table(name = "admin")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "password")
private String password;
@Column(name = "age")
private Integer age;
@Column(name = "sex")
private String sex;
@Column(name = "phone")
private String phone;
@Transient
private Integer currentPage;
@Transient
private Integer pageSize;
}
注: @Column注解的字段与数据库字段一致可省略,@Transient注解的字段代表不是数据中的字段。