封装统一的返回数据结构
public class Result {
private static final String SUCCESS = "0";
private static final String ERROR = "-1";
private String code;
private String msg;
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 msg) {
Result result = new Result();
result.setCode(ERROR);
result.setMsg(msg);
return result;
}
}
Vue安装axios,封装request
npm i axios -S
在src目录下,创建一个utils包,用来存放我们自己定义的工具,在utils包里创建一个request.js,来封装request请求
import axios from 'axios'
// 创建一个axios对象出来
const request = axios.create({
baseURL: 'http://localhost:8080',
timeout: 5000
})
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
// config.headers['token'] = user.token; // 设置请求头
return config
}, error => {
return Promise.reject(error)
});
// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
response => {
// response.data即为后端返回的Result
let res = response.data;
// 兼容服务端返回的字符串数据
if (typeof res === 'string') {
res = res ? JSON.parse(res) : res
}
return res;
},
error => {
console.log('err' + error) // for debug
return Promise.reject(error)
}
)
export default request
查询所有管理员信息
查询上节课的用户信息,我们把后台全部改成管理员,然后我们写一个查询请求
export default {
name: "AdminView",
data() {
return {
tableData: []
}
},
created() {
this.load();
},
methods: {
load() {
request.get("/admin").then(res => {
if (res.code === '0') {
this.tableData = res.data;
}
})
},
}
}
解决跨域问题:
admin:1 Access to XMLHttpRequest at 'http://localhost:8080/user/getUser' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
可以在controller上加个注解:@CrossOrigin
也有其他办法,可以百度搜索,有很多解决跨域的问题
INSERT INTO `admin` VALUES (11, '江月11', '123456', '男', 25, '18888889999');
INSERT INTO `admin` VALUES (12, '等雨停12', '123456', '女', 25, '18899998888');
INSERT INTO `admin` VALUES (13, '江月13', '123456', '男', 25, '18888889999');
INSERT INTO `admin` VALUES (14, '等雨停14', '123456', '女', 25, '18899998888');
INSERT INTO `admin` VALUES (15, '江月15', '123456', '男', 25, '18888889999');
INSERT INTO `admin` VALUES (16, '等雨停16', '123456', '女', 25, '18899998888');
INSERT INTO `admin` VALUES (17, '江月17', '123456', '男', 25, '18888889999');
INSERT INTO `admin` VALUES (18, '等雨停18', '123456', '女', 25, '18899998888');
INSERT INTO `admin` VALUES (19, '江月19', '123456', '男', 25, '18888889999');
INSERT INTO `admin` VALUES (20, '等雨停20', '123456', '女', 25, '18899998888');
按条件查询管理员信息
- AdminView.vue
<el-input v-model="params.name" style="width: 200px" placeholder="请输入姓名"></el-input>
<el-input v-model="params.phone" style="width: 200px; margin-left: 5px" placeholder="请输入电话"></el-input>
<el-button type="warning" style="margin-left: 10px" @click="findBySearch()">查询</el-button>
// data里定义一个params
params: {
name: '',
phone: ''
},
// methods里定义一个findBySearch
findBySearch() {
request.get("/admin/search", {
params: this.params
}).then(res => {
if (res.code === '0') {
this.tableData = res.data;
} else {
}
})
},
- 在entity包里创建一个实体类接收参数,Params.java
public class Params {
private String name;
private String phone;
}
- AdminController.java
@GetMapping("/search")
public Result findBySearch(Params params) {
List<Admin> list = adminService.findBySearch(params);
return Result.success(list);
}
- AdminService.java
public List<Admin> findBySearch(Params params) {
return adminDao.findBySearch(params);
}
- AdminDao.java
List<Admin> findBySearch(@Param("params") Params params);
- AdminMapper.xml
<select id="findBySearch" resultType="com.example.entity.Admin">
select * from admin
<where>
<if test="params != null and params.name != null and params.name != ''">
and name like concat('%', #{ params.name }, '%')
</if>
<if test="params != null and params.phone != null and params.phone != ''">
and phone like concat('%', #{ params.phone }, '%')
</if>
</where>
</select>
分页查询管理员信息
- pom.xml里导入分页插件依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
- application.yml拷贝好分页配置
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
- AdminView.vue
<el-button type="warning" @click="reset()">清空</el-button>
<div style="margin-top: 10px">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="params.pageNum"
:page-sizes="[5, 10, 15, 20]"
:page-size="params.pageSize"
layout="total, sizes, prev, pager, next"
:total="total">
</el-pagination>
</div>
params: {
name: '',
phone: '',
pageNum: 1,
pageSize: 5
},
total: 0
reset() {
this.params = {
pageNum: 1,
pageSize: 5,
name: '',
phone: ''
}
this.findBySearch();
},
handleSizeChange(pageSize) {
this.params.pageSize = pageSize;
this.findBySearch();
},
handleCurrentChange(pageNum) {
this.params.pageNum = pageNum;
this.findBySearch();
},
- AdminController.java
@GetMapping("/search")
public Result findBySearch(Params params) {
PageInfo<Admin> info = adminService.findBySearch(params);
return Result.success(info);
}
- AdminService.java
public PageInfo<Admin> findBySearch(Params params) {
// 开启分页查询
PageHelper.startPage(params.getPageNum(), params.getPageSize());
// 接下来的查询会自动按照当前开启的分页设置来查询
List<Admin> list = adminDao.findBySearch(params);
return PageInfo.of(list);
}
注:如果你启动项目遇到了循环依赖问题:
可以在application.yml里配置一个允许循环依赖:
spring:
main:
allow-circular-references: true
新增、编辑管理员信息
el-dialog:Element - The world's most popular Vue UI framework
- AdminView.vue
<el-button type="primary" style="margin-left: 10px" @click="add()">新增</el-button>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" @click="edit(scope.row)">编辑</el-button>
<el-button type="danger">删除</el-button>
</template>
</el-table-column>
<div>
<el-dialog title="请填写信息" :visible.sync="dialogFormVisible" width="30%">
<el-form :model="form">
<el-form-item label="姓名" label-width="15%">
<el-input v-model="form.name" autocomplete="off" style="width: 90%"></el-input>
</el-form-item>
<el-form-item label="性别" label-width="15%">
<el-radio v-model="form.sex" label="男">男</el-radio>
<el-radio v-model="form.sex" label="女">女</el-radio>
</el-form-item>
<el-form-item label="年龄" label-width="15%">
<el-input v-model="form.age" autocomplete="off" style="width: 90%"></el-input>
</el-form-item>
<el-form-item label="电话" label-width="15%">
<el-input v-model="form.phone" autocomplete="off" style="width: 90%"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="submit()">确 定</el-button>
</div>
</el-dialog>
</div>
dialogFormVisible: false,
form: {}
add() {
this.form = {};
this.dialogFormVisible = true;
},
edit(obj) {
this.form = obj;
this.dialogFormVisible = true;
},
submit() {
request.post("/admin", this.form).then(res => {
if (res.code === '0') {
this.$message({
message: '操作成功',
type: 'success'
});
this.dialogFormVisible = false;
this.findBySearch();
} else {
this.$message({
message: res.msg,
type: 'success'
});
}
})
}
- AdminController.java
@PostMapping
public Result save(@RequestBody Admin admin) {
if (admin.getId() == null) {
adminService.add(admin);
} else {
adminService.update(admin);
}
return Result.success();
}
- AdminService.java
public void add(Admin admin) {
// 初始化一个密码
if (admin.getPassword() == null) {
admin.setPassword("123456");
}
adminDao.insertSelective(admin);
}
public void update(Admin admin) {
adminDao.updateByPrimaryKeySelective(admin);
}
- 操作后的提示信息
Element - The world's most popular Vue UI framework
删除管理员信息
el-popconfirm:
- AdminView.vue
<el-popconfirm title="确定删除吗?" @confirm="del(scope.row.id)">
<el-button slot="reference" type="danger" style="margin-left: 5px">删除</el-button>
</el-popconfirm>
del(id) {
request.delete("/admin/" + id).then(res => {
if (res.code === '0') {
this.$message({
message: '删除成功',
type: 'success'
});
this.findBySearch();
} else {
this.$message({
message: res.msg,
type: 'success'
});
}
})
}
- AdminController.java
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
adminService.delete(id);
return Result.success();
}
- AdminService.java
public void delete(Integer id) {
adminDao.deleteByPrimaryKey(id);
}
注意:
缩小页面报错(错误消息 "ResizeObserver loop limit exceeded" 表明 ResizeObserver 触发了一系列的大小调整事件,导致浏览器超过了处理限制。这通常发生在你的代码直接或间接引起被观察元素大小频繁变化,从而反复触发 ResizeObserver。)
错误通常是在浏览器页面重置大小时,由于观察元素的大小变化导致的循环问题。是由 webpack引起的,出现在webpack-dev-server的overlay.js文件中
解决方法:
在App.vue的<script></script>中添加以下内容:
const debounce = (fn, delay) => {
let timer = null;
return function () {
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
}
}
const _ResizeObserver = window.ResizeObserver;
window.ResizeObserver = class ResizeObserver extends _ResizeObserver{
constructor(callback) {
callback = debounce(callback, 16);
super(callback);
}
}