0%

前后端分离CRUD基于vue+springboot

前后端分离下的CRUD实现(回顾)

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
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
<template>
<div>
<!-- 面包屑导航 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>权限管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
<!--用户列表主体-->
<!-- 卡片视图区 -->
<el-card>
<el-row :gutter="25">
<el-col :span="10">
<!-- 搜索添加 -->
<el-input placeholder="请输入搜索内容" v-model="queryInfo.query" clearable @clear="getUserList">
<el-button slot="append" icon="el-icon-search" @click="getUserList"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="addDialogVisible = true">添加用户</el-button>
</el-col>
</el-row>

<!-- 用户列表 border 边框 stripe 隔行变色 -->
<el-table :data="userlist" border stripe class="table-margin">
<el-table-column type="index"></el-table-column><!--索引列-->
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="邮箱" prop="email"></el-table-column>
<el-table-column label="密码(md5加密)" prop="password"></el-table-column>
<el-table-column label="角色" prop="role"></el-table-column>
<el-table-column label="状态" prop="state">
<!--作用域插槽 scope.row 存储了当前行的信息 -->
<template slot-scope="scope"><!--数据模板-->
<el-switch v-model="scope.row.state" @change="userStateChanged(scope.row)"></el-switch>
</template>
</el-table-column>
<!--自定义插槽-->
<el-table-column label="操作">
<template slot-scope="scope">
<!-- 修改 -->
<el-button type="primary" icon="el-icon-edit" size="mini" @click="showUpdateDialog(scope.row.id)"></el-button>
<!-- 删除 -->
<el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteUser(scope.row.id)"></el-button>
<!-- 权限 -->
<el-tooltip effect="dark" content="分配权限" placement="top-start" :enterable="false"><!--文字提示 enterable 隐藏-->
<el-button type="warning" icon="el-icon-setting" size="mini"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>

<div>
<!-- 分页 size-change 每页最大数变化 current-change 页数变化 layout 功能组件-->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pageNum"
:page-sizes="[2, 5, 100]"
:page-size="queryInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</el-card>
<!-- 新增用户 -->
<el-dialog title="添加用户" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed">
<el-form :model="addForm" :rules="rules" ref="addFormRef" label-width="70px">
<el-form-item label="用户名" prop="username">
<el-input v-model="addForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="addForm.password"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="addForm.email"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取消</el-button>
<el-button type="primary" @click="addUser">添加</el-button>
</span>
</el-dialog>

<el-dialog title="修改用户" :visible.sync="updateDialogVisible" width="50%" @close="updateDialogClosed">
<el-form :model="updateForm" :rules="rules" ref="updateFormRef" label-width="70px">
<el-form-item label="用户名" prop="username">
<el-input v-model="updateForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="updateForm.password"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="updateForm.email"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="updateDialogVisible = false">取消</el-button>
<el-button type="primary" @click="updateUser">修改</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
export default{
created() {
this.getUserList();
},
data() {
return {
// 请求数据
queryInfo: {
query: "",
pageNum: 1,
pageSize: 5
},
userlist: [],// 用户列表
total: 0, // 最大数据记录
addDialogVisible: false,
addForm:{
username:'',
password:'',
email:'',
},
updateForm:{

},
updateDialogVisible: false,
rules:{
//校验用户名
username:[
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 4, max: 12, message: '长度在 4 ~ 12 个字符', trigger: 'blur' }
],
//校验密码
password:[
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 12, message: '长度在 6 ~ 12 个字符', trigger: 'blur' }
],
email:[
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ min: 5, max: 25, message: '格式不正确', trigger: 'blur' }
]
},
}
},
methods:{
async getUserList() {
// 调用get请求
const { data: res } = await this.$http.get("/allUser", {
params: this.queryInfo
});
this.userlist = res.data; // 将返回数据赋值
this.total = res.numbers; // 总个数
},
// 监听pageSize改变的事件
handleSizeChange(newSize) {
this.queryInfo.pageSize = newSize;
this.getUserList(); // 数据发生改变重新申请数据
},
// 监听pageNum改变的事件
handleCurrentChange(newPage) {
this.queryInfo.pageNum = newPage;
this.getUserList(); // 数据发生改变重新申请数据
},
async userStateChanged(userinfo) {
const { data: res } = await this.$http.get(
"/userState", {
params: {id:userinfo.id,state:userinfo.state}
}
);
if (res != "success") {
userinfo.state = !userinfo.state;
return this.$message.error("账号状态更新失败!");
}
this.$message.success("账号状态已更新!");
},
addDialogClosed(){
this.$refs.addFormRef.resetFields();
},
addUser(){
this.$refs.addFormRef.validate(async vaild=>{
if(!vaild){
return;
}
const {data:res} = await this.$http.post("/addUser",this.addForm);
if(res!="success"){
return this.$message.error("添加失败!");
}
this.$message.success("添加成功!");
this.addDialogVisible = false;
this.getUserList();
})
},
async deleteUser(id){
const confirmResult = await this.$confirm('此操作将永久删除用户,是否继续?','提示',{
confirmButtonText:'确定',
cancelButtonText:'取消',
type:'warning'
}).catch(err => err);
if(confirmResult!='confirm'){
return this.$message.warning("已取消删除!");
}
const {data:res} = await this.$http.get("/deleteUser",{
params: {id:id}
});
if(res!="success"){
return this.$message.error("删除失败!");
}
this.$message.success("删除成功!");
this.getUserList();
},
async showUpdateDialog(id){
const {data:res} = await this.$http.get("/getUpdateUser",{
params: {id:id}
});
this.updateForm = res;
this.updateDialogVisible = true;
},
updateDialogClosed(){
this.$refs.updateFormRef.resetFields();
},
updateUser(){
this.$refs.updateFormRef.validate(async vaild=>{
if(!vaild){
return;
}
const {data:res} = await this.$http.post("/updateUser",this.updateForm);
if(res!="success"){
return this.$message.error("更新失败!");
}
this.$message.success("更新成功!");
this.updateDialogVisible = false;
this.getUserList();
});
},

},
}
</script>

<style lang="less">
/* 面包屑样式 */
.el-breadcrumb{
margin-bottom: 15px;
font-size: 16px;
}
</style>

路由设置:

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
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import Home from '../components/Home.vue'
import Welcome from '../components/welcome.vue'
import UserList from '../components/admin/UserList.vue'

Vue.use(VueRouter)

const routes = [
{
path: "/",
redirect: "/login"
},
{
path: "/login",
component: Login
},
{
path: "/home",
component: Home,
redirect: "/welcome",
children:[
{path: "/welcome",component: Welcome,},
{path: "/user",component: UserList,},
]
},
]

const router = new VueRouter({
routes
})

// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to:将要访问的路径
// from:从哪里访问的路径
// next:之后要做的任务,是一个函数
// next()放行, next('/URL')强制跳转的路径。
if (to.path == '/login') return next();// 访问路径为登录
// 获取flag
const userInfo = window.sessionStorage.getItem("user");// session取值
if (!userInfo) return next('/login');// 没登录去登录
next();
})

export default router

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
import './assets/css/global.css'
import './assets/font/iconfont.css'
import axios from 'axios'

//挂载axios
Vue.prototype.$http = axios
//设置访问根路径
axios.defaults.baseURL = "http://localhost:8081"

Vue.config.productionTip = false

new Vue({
router,
render: h => h(App)
}).$mount('#app')

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
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
@RestController
public class UserController {

@Autowired
private UserDao userDao;

@GetMapping("/allUser")
public String getUserList(QueryInfo queryInfo){
int numbers = userDao.getUserCounts("%" + queryInfo.getQuery() + "%");
int pageStart = (queryInfo.getPageNum()-1)*queryInfo.getPageSize();
List<User> users = userDao.getAllUser("%"+queryInfo.getQuery()+"%",pageStart,queryInfo.getPageSize());
HashMap<String, Object> res = new HashMap<>();
res.put("numbers",numbers);
res.put("data",users);
return JSON.toJSONString(res);
}

@GetMapping("/userState")
public String updateUserState(@RequestParam("id") Integer id,
@RequestParam("state") Boolean state){
int i = userDao.updateState(id, state);
return i >0?"success":"error";
}

@PostMapping("/addUser")
public String addUser(@RequestBody User user){
user.setRole("普通用户");
user.setState(false);
user.setPassword(MD5Utils.code(user.getPassword()));
int i = userDao.addUser(user);
return i>0?"success":"error";
}

@GetMapping("/deleteUser")
public String deleteUser(int id){
int i = userDao.deleteUser(id);
return i>0?"success":"error";
}

@GetMapping("/getUpdateUser")
public String getUpdateUser(int id){
User user = userDao.getUpdateUser(id);
return JSON.toJSONString(user);
}

@PostMapping("/updateUser")
public String updateUser(@RequestBody User user){
user.setPassword(MD5Utils.code(user.getPassword()));
int i = userDao.updateUser(user);
return i>0?"success":"error";
}
}

UserMapper.xml

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
<?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.fanchen.sport.dao.UserDao">
<select id="getUserByMessage" resultType="com.fanchen.sport.pojo.User">
select * from easyuser where username = #{username} and state = 1
</select>

<select id="getAllUser" resultType="com.fanchen.sport.pojo.User">
SELECT * FROM easyuser
<if test="username !=null ">
WHERE username like #{username}
</if>
LIMIT #{pageStart},#{pageSize}
</select>

<select id="getUserCounts" resultType="java.lang.Integer">
SELECT count(*) FROM `easyuser`
<if test="username !=null ">
WHERE username like #{username}
</if>
</select>

<update id="updateState">
UPDATE easyuser SET state = #{state} WHERE id = #{id}
</update>

<insert id="addUser">
insert into easyuser (username,password,email,role,state) values (#{username},#{password},#{email},#{role},#{state})
</insert>

<delete id="deleteUser">
delete from easyuser where id = #{id}
</delete>

<select id="getUpdateUser" resultType="com.fanchen.sport.pojo.User">
select * from easyuser where id = #{id}
</select>

<update id="updateUser">
update easyuser set username = #{username}, password = #{password},email = #{email} where id = #{id}
</update>
</mapper>

本文标题:前后端分离CRUD基于vue+springboot

文章作者:fanchen

发布时间:2021年01月19日 - 22:38:32

最后更新:2021年02月05日 - 17:59:34

原始链接:http://88fanchen.github.io/posts/9590b4fb/

许可协议:署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。