SpringBoot+Vue前后端分离简易开发

本文主要是学习于B站的Spring Boot+Vue前后端分离开发,技术主要采用Springboot + Vue + Element Ui,来完成基本的数据表格操作。

前端

界面



代码

main.js

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

//element-ui的全部组件
import ElementUI from 'element-ui'
//element-ui的css
import 'element-ui/lib/theme-chalk/index.css'
//使用elementUI
Vue.use(ElementUI)

Vue.config.productionTip = false

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

router

index.js

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 List from '../views/PageOne'
import Add from '../views/PageTwo'
import Update from '../views/PageThree.vue'
import PageFour from '../views/PageFour.vue'
import Index from '../views/index.vue'

Vue.use(VueRouter)

const routes = [{
path: "/",
name: "用户管理",
component: Index,
redirect: "/List",
show: true,
children: [{
path: "/List",
name: "查询用户",
component: List
},
{
path: "/Add",
name: "添加用户",
component: Add
},
{
path: "/update",
name: "修改用户",
component: Update
}
]
},
{
path: "/authority",
name: "权限管理",
// 利用v-show隐藏此模块
show: false
}
]

const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})

export default router

App.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
<template>
<div>
<router-view></router-view>
</div>
</template>

<style>
.el-header {
background-color: #b3c0d1;
color: #333;
line-height: 60px;
}

.el-aside {
color: #333;
}
</style>

<script>
export default {
data() {
const item = {
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
};
return {
tableData: Array(20).fill(item)
};
}
};
</script>

views

index.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
<template>
<div>
<!-- 构建整个页面框架 -->
<el-container style="height: 500px; border: 1px solid #eee">
<!-- 构建左侧菜单 -->
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<!-- 左侧菜单内容,
常用属性 :default-openeds默认展开的菜单,通过菜单的index直来关联
default-active:默认选中的菜单,通过菜单的index值来关联-->
<!-- <el-menu :default-openeds="['1', '3']">
可展开的菜单,常用属性,index:菜单的下标,文本类型,不能是数值类型
<el-submenu index="1">
对应el-submenu的菜单名
<template slot="title">
i:设置菜单图标,通过class属性实则. 如:el-icon-menu,el-icon-message,el-icon-setting
<i class="el-icon-message"></i>导航一
</template>
菜单的子节点,不可再展开,常用属性. index:菜单的下标,文本类型,不能是数值类型
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
<el-submenu index="1-3">
<template slot="title">
<i class="el-icon-message"></i>选项3
</template>
<el-menu-item index="1-3-1">选项3-1</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu> -->

<!-- menu 与 router的绑定:
1.<el-menu>标签添加router属性
2.在页面中添加<router-view>标签,它是一个容器,动态渲染你选择的router
3.<el-menu-item>标签的index值就是要跳转的router
-->
<el-menu router :default-openeds="['0', '1']">
<!-- Custom elements in iteration require 'v-bind:key' directives. -->
<!-- 在el-menu-item 及el-submenu 标签上面,必须要加上 index属性,如果没有则报错。
:key属性为了避免点击菜单全部展开-->
<el-submenu v-for="(item,index) in $router.options.routes" :index="index + ''" :key="index + ''" v-show="item.show">
<template slot="title"><i class="el-icon-message"></i>{{index}}-{{item.name}}</template>
<el-menu-item v-for="(item2,index2) in item.children"
:class="$route.path == item2.path ? 'isActive':''" :index="item2.path" v-bind:key="index + '-' + index2">
<!-- <router-link :to="/路径"></router-link> -->
{{item2.name}}
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>

<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropdown-item>
<el-dropdown-item>新增</el-dropdown-item>
<el-dropdown-item>删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>王小虎</span>
</el-header>

<!-- 构建页面主体内容 -->
<el-main>
<!-- <el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140"></el-table-column>
<el-table-column prop="name" label="姓名" width="120"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>-->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>

<style scoped>
.isActive:hover {
color: aquamarine;
font-weight: bold;
}
</style>

PageOne.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
<template>
<!-- 必须都套在一个div里 -->
<div>
<el-table :data="tableData" border style="width: 50%">
<el-table-column fixed prop="id" label="编号" width="150"></el-table-column>
<el-table-column prop="name" label="姓名" width="120"></el-table-column>
<el-table-column prop="gender" label="性别" width="120"></el-table-column>
<el-table-column prop="age" label="年龄" width="120"></el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="edit(scope.row)" type="text" size="small">修改</el-button>
<el-button @click="deleteUserById(scope.row)" type="text" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<!-- :total 默认每页十条记录数,总记录数是100,就是十页
:page-size: 每页数据量(即记录数),默认10-->
<el-pagination
background
layout="prev, pager, next"
:page-size="pageSize"
:total="total"
@current-change="page"
></el-pagination>
</div>
</template>

<script>
export default {
name: "PageOne",
methods: {
edit(row) {
this.$router.push({
path: '/update',
query: {
id: row.id
}
})
},
deleteUserById(row) {
alert(row.id)
const _this = this;
axios
.delete("http://localhost:8181/user/delete?id=" + row.id)
.then(function(resp) {
alert("成功");
window.location.reload();
}).catch(err => {
alert("失败")
});
},
page(currentPage) {
const _this = this;
axios
.get("http://localhost:8181/user/findAll/" + (currentPage - 1) + "/6")
.then(function(resp) {
_this.tableData = resp.data.content;
_this.pageSize = resp.data.size;
_this.total = resp.data.totalElements;
});
}
},
data() {
return {
pageSize: 1,
total: 17,
tableData: []
};
},
created() {
const _this = this;
axios.get("http://localhost:8181/user/findAll/0/5").then(function(resp) {
_this.tableData = resp.data.content;
_this.pageSize = resp.data.size;
_this.total = resp.data.totalElements;
});
}
};
</script>

<style scoped>
</style>

PageTwo-页面添加功能

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
<template>
<div>
<!-- ref:不能少,相当于form表单的name属性 -->
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="用户姓名" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="用户性别" prop="gender">
<el-input v-model="ruleForm.gender"></el-input>
</el-form-item>
<el-form-item label="用户年龄" prop="age">
<el-input v-model="ruleForm.age"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
<el-button @click="test()">Test</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "PageTwo",
data() {
return {
ruleForm: {
name: "",
age: "",
gender: ""
// region: "",
// date1: "",
// date2: "",
// delivery: false,
// type: [],
// resource: "",
// desc: ""
},
// 定义rules对象,在rules对象中设置表单各个选项的校验规则:
// trigger:触发事件,如 blur失焦
rules: {
id: [
{ required: true, message: "请输入用户编号", trigger: "blur" },
{ min: 1, max: 5, message: "长度在 1 到 5 个字符", trigger: "blur" }
],
name: [
{ required: true, message: "请输入用户名称", trigger: "blur" },
{ min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
],
region: [
{ required: true, message: "请选择活动区域", trigger: "change" }
]
}
};
},
methods: {
test() {
// 不能拼接 "内容" +,会变成Object
console.log(this.ruleForm);
},
submitForm(formName) {
const _this = this;
this.$refs[formName].validate(valid => {
if (valid) {
// axios.post('http://localhost:8181/user/add', this.ruleForm)
// .then(function (response) {
// console.log(response);
// })
axios({
url: "http://localhost:8181/user/add",
params: {
name: this.ruleForm.name,
age: this.ruleForm.age,
gender: this.ruleForm.gender
},
method: "post"
}).then(res => {
_this.$alert("《" + _this.ruleForm.name + "》添加成功", "消息", {
confirmButtonText: "确定",
callback: action => {
_this.$router.push("/List");
}
});
});
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
};
</script>

PageThree-页面修改功能

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
<template>
<div>
<!-- ref:不能少,相当于form表单的name属性 -->
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="用户编号">
<el-input v-model="ruleForm.id"></el-input>
</el-form-item>
<el-form-item label="用户姓名" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="用户性别" prop="gender">
<el-input v-model="ruleForm.gender"></el-input>
</el-form-item>
<el-form-item label="用户年龄" prop="age">
<el-input v-model="ruleForm.age"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">修改</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "PageThree",
data() {
return {
ruleForm: {
id: "",
name: "",
age: "",
gender: ""
// region: "",
// date1: "",
// date2: "",
// delivery: false,
// type: [],
// resource: "",
// desc: ""
},
// 定义rules对象,在rules对象中设置表单各个选项的校验规则:
// trigger:触发事件,如 blur失焦
rules: {
id: [
{ required: true, message: "请输入用户编号", trigger: "blur" },
{ min: 1, max: 5, message: "长度在 1 到 5 个字符", trigger: "blur" }
],
name: [
{ required: true, message: "请输入用户名称", trigger: "blur" },
{ min: 2, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
],
region: [
{ required: true, message: "请选择活动区域", trigger: "change" }
]
}
};
},
methods: {
submitForm(formName) {
const _this = this;
this.$refs[formName].validate(valid => {
if (valid) {
// axios.post('http://localhost:8181/user/add', this.ruleForm)
// .then(function (response) {
// console.log(response);
// })
axios({
url: "http://localhost:8181/user/update",
params: {
id: this.ruleForm.id,
name: this.ruleForm.name,
age: this.ruleForm.age,
gender: this.ruleForm.gender
},
method: "put"
}).then(res => {
_this.$alert("《" + _this.ruleForm.name + "》修改成功", "消息", {
confirmButtonText: "确定",
callback: action => {
_this.$router.push("/List");
}
});
});
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
},
created() {
const _this = this;
alert(this.$route.query.id);
axios
.get("http://localhost:8181/user/findById/" + this.$route.query.id)
.then(function(response) {
_this.ruleForm = response.data;
});
}
};
</script>

后端

UserInfo.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
package cn.blue.demo.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
* @author Blue
* @date 2020/2/11
**/
@Data
@Entity
public class UserInfo {
/**
* 设置自增
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

private String name;

private String gender;

private Integer age;
}

UserInfoRepository.java

1
2
3
4
5
6
7
8
9
10
11
12
package cn.blue.demo.repository;

import cn.blue.demo.entity.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;

/**
* @author Blue
* @date 2020/2/11
**/
public interface UserInfoRepository extends JpaRepository<UserInfo, Integer> {
//右键 goto,创建测试类
}

UserInfoController.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
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
package cn.blue.demo.controller;

import cn.blue.demo.entity.UserInfo;
import cn.blue.demo.repository.UserInfoRepository;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
* @author Blue
* @date 2020/2/11
**/
@RestController
@RequestMapping("/user")
public class UserInfoController {
@Autowired
private UserInfoRepository userInfoRepository;

/**
*
* @param page 当前页数
* @param size 每页显示数据量
* @return 用户列表信息;倘若让其直接通过访问user就请求此方法就是404
*/
@GetMapping("/findAll/{page}/{size}")
public Page<UserInfo> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size) {
PageRequest pageRequest = PageRequest.of(page, size);
return userInfoRepository.findAll(pageRequest);
}

@PostMapping("/add")
@ResponseBody
public String add(UserInfo userInfo) {
UserInfo user = userInfoRepository.save(userInfo);
if (user != null) {
return "success";
} else {
return "error";
}
}

@GetMapping("findById/{id}")
public UserInfo findById(@PathVariable("id") Integer id) {
return userInfoRepository.findById(id).get();
}

@PutMapping("/update")
public String update(UserInfo userInfo) {
if(userInfoRepository.save(userInfo) != null) {
return "success";
} else{
return "error";
}
}

@DeleteMapping("/delete")
public String delete(@RequestParam("id") Integer id) {
try {
UserInfo userInfo = new UserInfo();
userInfo.setId(id);
userInfoRepository.delete(userInfo);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}
}

配置类CorsConfig: 解决跨域问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package cn.blue.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* @author Blue
* @date 2020/2/11
* 解决跨域的问题
**/
@Configuration
public class CorsConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}

pom.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
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  1. © 2020 Liu Yang    湘ICP备20003709号

请我喝杯咖啡吧~

支付宝
微信