SpringBoot +Vue前后端分离(笔记)

您所在的位置:网站首页 前后端分离的概念是什么意思 SpringBoot +Vue前后端分离(笔记)

SpringBoot +Vue前后端分离(笔记)

2024-07-16 06:02:30| 来源: 网络整理| 查看: 265

前后端分离简介

前后端分离

前后端分离就是将⼀个应⽤的前端代码和后端代码分开写,为什么要这样做?

如果不使⽤前后端分离的⽅式,会有哪些问题?

传统的 Java Web 开发中,前端使⽤ JSP 开发,JSP 不是由后端开发者来独⽴完成的。

前端—》HTML 静态⻚⾯ —〉后端 —》JSP

这种开发⽅式效率极低,可以使⽤前后端分离的⽅式进⾏开发,就可以完美地解决这⼀问题。

前端只需要独⽴编写客户端代码,后端也只需要独⽴编写服务端代码提供数据接⼝即可。

前端通过 Ajax 请求来访问后端的数据接⼝,将 Model 展示到 View 中即可。

前后端开发者只需要提前约定好接⼝⽂档(URL、参数、数据类型…),然后分别独⽴开发即可,前端

可以造假数据进⾏测试,完全不需要依赖于后端,最后完成前后端集成即可,真正实现了前后端应⽤的

解耦合,极⼤地提升了开发效率。

单体—》前端应⽤ + 后端应⽤

前端应⽤:负责数据展示和⽤户交互。

后端应⽤:负责提供数据处理接⼝。

前端 HTML —》Ajax —〉RESTful 后端数据接⼝。

传统的单体应⽤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VkFL4q5b-1610345829474)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210111112048520.png)]

前后端分离的结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5usU00y-1610345829478)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210111112106144.png)]

前后端分离就是将⼀个单体应⽤拆分成两个独⽴的应⽤,前端应⽤和后端应⽤以 JSON 格式进⾏数据交互。

实现技术

Spring Boot + Vue

使⽤ Spring Boot 进⾏后端应⽤开发,使⽤ Vue 进⾏前端应⽤开发。

Vue + Element UI

Vue 集成 Element UI

Element UI 后台管理系统主要的标签:

el-container:构建整个⻚⾯框架。

el-aside:构建左侧菜单。

el-menu:左侧菜单内容,常⽤属性:

:default-openeds:默认展开的菜单,通过菜单的 index 值来关联。

:default-active:默认选中的菜单,通过菜单的 index 值来关联。

el-submenu:可展开的菜单,常⽤属性:

index:菜单的下标,⽂本类型,不能是数值类型。

template:对应 el-submenu 的菜单名。

i:设置菜单图标,通过 class 属性实则。

el-icon-messae

el-icon-menu

el-icon-setting

el-menu-item:菜单的⼦节点,不可再展开,常⽤属性:

index:菜单的下标,⽂本类型,不能是数值类型。

Vue router 来动态构建左侧菜单

导航1

⻚⾯1

⻚⾯2

导航2

⻚⾯3

⻚⾯4

menu 与 router 的绑定

1、 标签添加 router 属性。

2、在⻚⾯中添加 标签,它是⼀个容器,动态渲染你选择的 router。

3、 标签的 index 值就是要跳转的 router。

Element UI 表单数据校验

定义 rules 对象,在 rules 对象中设置表单各个选项的校验规则

required: true, 是否为必填项

message: ‘error’, 提示信息

trigger: ‘blur’,触发事件

Demo最终效果:

在这里插入图片描述 在这里插入图片描述

项目结构:

在这里插入图片描述 在这里插入图片描述

环境准备 jdk 1.8maven 3.6.3IntelliJ IDEA 2019.3 安装vue.js插件 在这里插入图片描述 SpringBoot *2.2.2* .RELEASE 在这里插入图片描述@vue/cli 4.2.2 (+ node.js) 👉 Vue CLI3开发环境搭建

新建Vue工程

命令行输入vue ui ( vue3+版本才有) 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

项目创建完成后添加插件element UI 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

用IDEA打开刚才创建的Vue项目,在IDEA的命令行终端输入npm run serve启动Vue ( ctrl + c 停止vue )

即可访问项目首页 http://localhost:8080 在这里插入图片描述

三、新建Spring Boot工程

创建Spring Boot工程需要的组件: 在这里插入图片描述 Lombok用于自动生成各种属性的 Setter 和 Getter 方法,省去手动生成。在数据库library中创建book表 DROP TABLE IF EXISTS `book`; /*!40101 SET @saved_cs_client = @@character_set_client */; SET character_set_client = utf8mb4 ; CREATE TABLE `book` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `author` varchar(20) DEFAULT NULL, `publish` varchar(20) DEFAULT NULL, `pages` int(10) DEFAULT NULL, `price` float(10,2) DEFAULT NULL, `bookcaseid` int(10) DEFAULT NULL, `abled` int(10) DEFAULT NULL, PRIMARY KEY (`id`), ) ENGINE=InnoDB AUTO_INCREMENT=119 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `book` -- LOCK TABLES `book` WRITE; /*!40000 ALTER TABLE `book` DISABLE KEYS */; INSERT INTO `book` VALUES (1,'解忧杂货店','东野圭吾','电子工业出版社',102,27.30,9,1), (2,'追风筝的人','卡勒德·胡赛尼','中信出版社',330,26.00,1,1), (3,'人间失格','太宰治','作家出版社',150,17.30,1,1), (4,'这就是二十四节气','高春香','电子工业出版社',220,59.00,3,1), (5,'白夜行','东野圭吾','南海出版公司',300,27.30,4,1), (6,'摆渡人','克莱儿·麦克福尔','百花洲文艺出版社',225,22.80,1,1), (7,'暖暖心绘本','米拦弗特毕','湖南少儿出版社',168,131.60,5,1), (8,'天才在左疯子在右','高铭','北京联合出版公司',330,27.50,6,1), (9,'我们仨','杨绛','生活.读书.新知三联书店',89,17.20,7,1), (10,'活着','余华','作家出版社',100,100.00,6,1), (11,'水浒传','施耐庵','三联出版社',300,50.00,1,1), (12,'三国演义','罗贯中','三联出版社',300,50.00,2,1), (13,'红楼梦','曹雪芹','三联出版社',300,50.00,5,1), (14,'西游记','吴承恩','三联出版社',300,60.00,3,1); /*!40000 ALTER TABLE `book` ENABLE KEYS */; UNLOCK TABLES;

删除mould。。。本地从新安装

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-46CTfKkF-1610345829481)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210110170030932.png)]

在这里插入图片描述 根据Element官网给出的样式实例代码进行相关修改 在这里插入图片描述 修改后的App.Vue 如下

导航一 分组一 选项1 选项2 .el-header { background-color: #B3C0D1; color: #333; line-height: 60px; } .el-aside { color: #333; } export default { data() { const item = { date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }; return { tableData: Array(20).fill(item) } } };

在这里插入图片描述

新建index.vue 在这里插入图片描述

export default { name: "Index" } App.Vue 实现整体框架(侧边栏),每次页面跳转的时候这个框架的样式是不变的.App.vue 中的router-view 套index ,index 的router-view 套其他界面,这样才能保证侧边栏一直存在。此后的每次页面跳转都只更改index的router-view中的内容

在这里插入图片描述

menu 与 router的绑定,实现页面跳转 新建前端页面

在views中新建

BookManager.vue (查询图书页面)、BookUpdate.vue(图书信息修改页面)、AddBook.vue(添加图书页面)` 配置路由(router/index.js ) import Vue from 'vue' import VueRouter from 'vue-router' import Index from "../views/Index"; import BookManager from "../views/BookManager"; import AddBook from "../views/AddBook"; import BookUpdate from "../views/BookUpdate"; Vue.use(VueRouter) const routes = [ { path: '/', name: '图书管理', show: true, component: Index, /* 首页地址直接跳转到/BookManager */ redirect: "/BookManager", children: [ { path: '/BookManager', name: '查询图书', component: BookManager }, { path: '/AddBook', name: '添加图书', component: AddBook }, ] }, { path: '/BookUpdate', // name: '修改图书', component: BookUpdate, show: false//开始时候先不显现出来 } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router 修改App.vue, 实现menu 与 router的绑定(页面跳转) 标签添加router属性在index页面中添加route-view标签,他是一个容器,动态渲染你选择的routerel-menu-item标签的index值就是要跳转的router {{item.name}} {{item2.name}} 前后端信息传递,显示图书信息 JPA 连接数据库配置 application.yml spring: datasource: # 连接数据库library url: jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver jpa: # 打印sql show-sql: true properties: hibernate: # 格式化sql format_sql: true server: port: 8181

vue已经默认占用了8080端口,修改springboot的端口为8181防止冲突

整合SpringData JPA, 编写一个实体类(bean)和数据表进行映射

在spring boot项目中新建实体类 entity/Book.java

/** * 使用Entity将该类与数据库表绑定,根据类名和表名经行绑定(默认类名小写就是表名); * * Data是lombok插件的方法,自动帮我们生成各种setter和getter方法 */ @Entity @Data public class Book { // 和数据库表中的id绑定,表示这是主键 @Id // 设置主键Id自增 @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String author; private String publish; private Integer pages; private Integer price; } 编写一个Dao接口来操作实体类对应的数据表(Repository)

新建 repository/ BookRepository.java

Spring Data 提供了统一的 repository 接口,实现了数据库的相关基本操作 在这里插入图片描述 继承 JpaRepository 来完成对数据库的操作

public interface BookRepository extends JpaRepository { } 新建Controller层处理浏览器请求

controller/ BookHandler.java

/** * RestController = @Controller + @ResponseBody * Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。 * 当然也有语义化的作用,即代表该类是充当Controller的作用 * ResponseBody 该类中所有的API接口返回的数据都会以Json字符串的形式返回给客户端 * * RequestMapping 提供路由信息,负责URL到Controller中的具体函数的映射。服务器发送 /book 请求时执行该类 * * 通过Handler数据才能调给前端使用 */ @RestController @RequestMapping("/book") public class BookHandler { @Autowired private BookRepository bookRepository; /** * 分页显示 * * GetMapping是一个组合注解 是@RequestMapping(method = RequestMethod.GET)的缩写 * page/size 表示从第几页开始,每页几个 */ @GetMapping("/findAll/{page}/{size}") public Page findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size){ PageRequest request = PageRequest.of(page,size); return bookRepository.findAll(request); } }

运行该项目

http://localhost:8181/book/findAll/0/6 表示从第0页开始,显示6个数据

前端发送Ajax请求8181端口获取后端数据

通过 axios 组件请求 Ajax axios 是目前应用最为广泛的 Ajax 封装库

终止vue服务后 在命令行输入vue add axios 安装axios 在这里插入图片描述修改 BookManager.vue created() 方法页面一打开就会调用page() 方法实现点击页数跳转 修改 删除 export default { methods: { page(currentPage){ const _this = this axios.get('http://localhost:8181/book/findAll/'+(currentPage-1)+'/10').then(function(resp){ console.log(resp) _this.tableData = resp.data.content _this.pageSize = resp.data.size _this.total = resp.data.totalElements }) } }, data() { return { pageSize: '', total: '', tableData: [ ] } }, created(){ const _this = this axios.get('http://localhost:8181/book/findAll/0/10').then(function(resp){ console.log(resp) _this.tableData = resp.data.content _this.pageSize = resp.data.size _this.total = resp.data.totalElements }) } }

访问 http://localhost:8080/BookManager (刷新浏览器) 查看控制台,出现跨域问题,前端无法获取后端数据 在这里插入图片描述

6. 解决跨域问题

在后端解决跨域问题: 新建配置类 config/ CrosConfig.java

/** * 解决跨域问题 */ @Configuration public class CrosConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); } } 修改

流程:

前端主页面点击修改按钮后端根据id查询此图书信息 findById前端发送ajax请求获取数据并跳转到修改页面 BookUpdate.vue前端传递修改后的信息给后端update函数处理返回主页面 BookHandler.hava /** * 根据Id查询图书信息 */ @GetMapping("/findById/{id}") public Book findById(@PathVariable("id") Integer id){ return bookRepository.findById(id).get(); } /** * 修改图书信息 * * PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源) * Post请求:后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源) */ @PutMapping("/update") public String update(@RequestBody Book book){ Book result = bookRepository.save(book); if(result != null){ return "success"; }else{ return "error"; } }

BookUpdate.vue核心代码

修改 重置 export default { data() { return { // 数据 ruleForm: { id: '', name: '', author: '', publish: '', pages: '', price: '', }, //校验规则 rules: { name: [ { required: true, message: '图书名称不能为空', trigger: 'blur' } ], author: [ { required: true, message: '作者姓名不能为空', trigger: 'blur' } ], publish: [ { required: true, message: '出版社不能为空', trigger: 'blur' } ], price: [ { required: true, message: '价格不能为空', trigger: 'blur' } ], } }; }, methods: { submitForm(formName) { const _this = this this.$refs[formName].validate((valid) => { if (valid) { /*put和后端的PutMapping对应!!!*/ axios.put('http://localhost:8181/book/update', this.ruleForm).then(function(resp){ if(resp.data == 'success'){ // 消息弹出框---- element官网找个模板直接复制 _this.$alert('《' + _this.ruleForm.name + '》修改成功!', '提示', { confirmButtonText: '确定', callback: action => { // 跳转界面 _this.$router.push('/BookManager') } }); } }) } else { return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } }, created() { const _this = this axios.get('http://localhost:8181/book/findById/' + this.$route.query.id ).then(function(resp){ _this.ruleForm = resp.data }) } }

在这里插入图片描述

添加 BookHandler.java /** * 添加图书 * * RequestBody 通过映射把前端Json数据转化成java对象 */ @PostMapping("/add") public String save(@RequestBody Book book){ Book result = bookRepository.save(book); if(result != null){ return "success"; }else{ return "error"; } } AddBook.vue 提交 重置 methods: { submitForm(formName) { const _this = this this.$refs[formName].validate((valid) => { if (valid) { axios.post('http://localhost:8181/book/add', this.ruleForm).then(function(resp){ if(resp.data == 'success'){ // 消息弹出框---- element官网找个模板直接复制 _this.$alert('《' + _this.ruleForm.name + '》添加成功!', '提示', { confirmButtonText: '确定', callback: action => { // 跳转界面 _this.$router.push('/BookManager') } }); } }) } else { return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } 删除

删除之后直接返回主界面 BookHandler.java

@DeleteMapping("/delete/{id}") public void delete(@PathVariable("id") Integer id){ bookRepository.deleteById(id); } BookManger.vue 修改 删除 deleteBook(row){ const _this = this axios.delete('http://localhost:8181/book/delete/' + row.id).then(function(resp){ // 消息弹出框---- element官网找个模板直接复制 _this.$alert('《' + row.name + '》删除成功!', '提示', { confirmButtonText: '确定', callback: action => { // 动态刷新此页面 window.location.reload() } }); }) },


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭