随着互联网的高速发展以及信息技术的不断升级,前后端分离已经逐渐曾为互联网项目开发的标准方式。在实际的开发工作中,前后端的接口测试占据了大量的前端开发人员的大量时间。
文章目录
- 背景
- 为什么需要分离前后端?
- 前后端分离的优点是什么?
- 如何传输数据和接口调用?
- 一、练手项目搭建
- 1.1 Vue项目的创建
- 1.2 SpringBoot项目的创建
- 1.2.1 导入数据库
- 1.2.2 Controller层代码
- 二、前后端整合
- 2.1 解决跨域访问的不同源问题
- 2.1.1 前端解决
- 2.1.2 后端解决
- 全局配置:fire::fire:
- 局部配置
- 三、前端具体实现
- 3.1前台项目结构
- 3.2 Element-ui的使用
- 3.2.1 打开方式
- :one:Container 布局容器
- :two:Table 表格
- :three: Form 表单
- 3.2.2 Vue router 来动态构建左侧菜单
- 3.2.3 menu 与 router 的绑定
- 3.2.4 表格的使用
- :one:安装axios
- :two:导入Axios全局配置URL
- :three: 在BookManage.vue里使用Axios进行数据调用渲染
- :four: 使用Elemenet-ui的分页组件完成分页
- :five: 使用Element-ui完成表单的校验
- 3.3 Axios的使用
- 3.3.1 打开方式
- 3.3.2 全局的axios配置
- 3.3.3 Axios封装的请求
- 四、总结
为什么需要分离前后端?
为了实现前端和后端人员的开发独立,达到专注自己的核心
把前端和后端独立开发,放在不同的服务器上,独立部署运行。这就是两个工程,这样,前后端的工作人员可以通过团队间的协商,约定一致的交互接口,实现同步开发。
这样。前端小伙伴只需要关注页面的样式和动效等展示效果,后端小伙伴就只需要关注数据的获取与业务逻辑的处理。
前后端分离的优点是什么?
- 提高团队见的开发效率,分工更加明确化。 前台页面的修改再也不需要考虑后台的事情,开发更加灵活。
- 前端不需要再向后端程序猿提供页面模板。 彻底脱离了JSP时代的影响
- 局部性能的提升。 通过前端路由的配置,可以实现页面的按需加载,异步的方式获取数据是的用户体验感增强。且获取数据的速率也变快。
- 降低维护成本 SpringBoot的流行给系统的开发节约了维护成本,代码重构性得到了很大的提升。
- 进一步的实现代码的高内聚,低耦合
- 系统可以更好地追求高并发,高可用,搞性能。给用户最好的体验感。
一、练手项目搭建【调用接口】
调用接口在现阶段肯定离不开Ajax,但是现在的技术对原生的Ajax经过封装与简化,产生了许多的异步传输技术,比如Axios。很好的与前端流行的框架Vue结合
【数据传输】
数据传输必然也就离不开Json,后端通过注解@RestController或者@ResponseBody,进行发送数据,就是以Json格式发送的,不过SpringBoot可以让用户按需的选择Json的解析器
- Jackson:Spring mvc 框架为SpringMVC内置的
- FastJson:Alibaab提供的,号称是最快的高性能的Json解析器
- Gson:谷歌提供的高效率的Json解析器
本练习项目所使用的技术SapringBoot2.6.6、Vue2.x、Element-ui、Axios、MyBatis、MySQL
1.1 Vue项目的创建Vue项目创建方式有多种,但是前提是必须要先安装好Node.js,关于Node的安装,如果没有安的话,自行baidu搜索。
1️⃣ 方式一:
通过Vue ui来创建vue项目
- 打开图形化界面
我们调出黑窗口(win+R),在窗口中敲入vue ui,进入到vue的可视化图形管理页面进行创建vue项目
- 进入Vue项目管理器,创建项目
我取消了git,选择包管理器为npm,并且为项目起一个名字,点击下一步
选择手动配置,点击下一步
取消勾选linter,并选中Router和Vuex版本管理,点击下一步
选择vue版本为2.x,点击创建
点击创建项目,不保存为预设,等待进度条加载需要加载包
2️⃣ 方式二:
通过黑窗口 vue命令的方式安装。自行百度,操作和用vue ui步骤是一样的。
vue create 项目名称 -- 创建项目 cd 项目路径 -- 进入到项目目录下 npm run serve -- 启动项目1.2 SpringBoot项目的创建
使用Spring提供的创建平台创建
注意项目所需要使用的依赖有:
- SpringBoot启动器
- MySQL
- Druid
- PageHelper
- Mybatis-Spring
- lombok
- log4j
- test
并完成后端项目框架的搭建
- pojo(数据实体包)
- mapper
- service
- controller
- config
- …
创建 一个library的数据库,导入一下数据,创建Book表并添加一些测试数据
DROp TABLE IF EXISTS `book`; 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; 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);1.2.2 Controller层代码
实现一个简单的CURD操做
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("bookService")
private BookService bookService;
@GetMapping("/queryAll")
public List queryAll(){
return bookService.queryAll();
}
@PostMapping("/queryByPage/{pageNum}/{pageSize}")
public PageInfo queryByPage(@PathVariable("pageNum") Integer pageNum,
@PathVariable("pageSize") Integer pageSize){
PageInfo pageInfo = bookService.queryByPage(pageNum, pageSize);
List list = pageInfo.getList();
long total = pageInfo.getTotal();
System.out.println("总记录数:" + total);
int prePage = pageInfo.getPrePage();
System.out.println("上一页:"+prePage);
int nextPage = pageInfo.getNextPage();
System.out.println("下一页:"+nextPage);
return pageInfo;
}
@PostMapping("/addBook")
public String addBook(@RequestBody Book book){
if (bookService.addBook(book)) {
return "添加一本"+book.getName();
}else {
return "添加失败!请重新添加";
}
}
@GetMapping("/queryById/{id}")
public Book queryById(@PathVariable("id") Integer id){
Book book = bookService.queryById(id);
return book;
}
@PostMapping("/updateBook")
public String updateBook(@RequestBody Book book){
if (bookService.updateById(book)) {
return "success";
}else {
return "false";
}
}
@DeleteMapping("/deleteBook/{id}")
public String deleteBook(@PathVariable("id") Integer id){
if (bookService.deleteById(id)) {
return "success";
}else {
return "false";
}
}
}
二、前后端整合
2.1 解决跨域访问的不同源问题
解决跨域问题主要分为两个方向:1、前端解决;2、后端解决
2.1.1 前端解决在vue的config目录下的index.js文件里设置跨域
proxyTable: {
'/apis':{ // 这里使用/apis来替换'http://localhost:8091'
target: 'http://localhost:8091',//这里是你的sprintboot项目中的后台接口
changeOrigin: true,//允许跨域
pathRewrite: {//重写路径
'^/apis':'/apis'//写'/apis'就相当于写'http://localhost:8091/apis'
}
}
2.1.2 后端解决
全局配置
全局配置是需要单独写一个配置文件类,在该配置类上实现WebMvcConfiguration接口,然后实现接口里面的方法addCorsMappings
- addMapping:表示对哪种格式的请求路径进行跨域处理。
- allowedHeaders:表示允许的请求头,默认允许所有的请求头信息。
- allowedMethods:表示允许的请求方法,默认是 GET、POST 和 HEAD。这里配置为 * 表示支持所有的请求方法。
- maxAge:表示探测请求的有效期
- allowedOrigins 表示支持的域
- allowedOriginPatterns 也表示支持的域 一般用于SpringBoot2.6.x之后的版本
@Configuration
public class CrossConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置 映射为
Vue.prototype.$axios = axios;
3️⃣ 在BookManage.vue里使用Axios进行数据调用渲染
使用create函数来进行数据的渲染
- created:在模板渲染成Html之前调用,通常初始化某些值的时候使用,渲染成视图
- mounted:在模板渲染成html之后调用,通常是初始化页面之后,在对html的dom进行操做
后端使用MyBatis的PageHelper完成分页操作
@PostMapping("/queryByPage/{pageNum}/{pageSize}")
public PageInfo queryByPage(@PathVariable("pageNum") Integer pageNum,
@PathVariable("pageSize") Integer pageSize){
PageInfo pageInfo = bookService.queryByPage(pageNum, pageSize);
List list = pageInfo.getList();
long total = pageInfo.getTotal();
System.out.println("总记录数:" + total);
int prePage = pageInfo.getPrePage();
System.out.println("上一页:"+prePage);
int nextPage = pageInfo.getNextPage();
System.out.println("下一页:"+nextPage);
return pageInfo;
}
使用CURL 命令进行测试
5️⃣ 使用Element-ui完成表单的校验elementui的分页功能是依靠两个重要的参数:
1、page-size:每页大小2、total:总记录数
定义 rules 对象,在 rules 对象中设置表单各个选项的校验规则
rules: {
name: [
{ required: true, message: 'error', trigger: 'blur' },
{ min: 3, max: 5, message: '⻓度在 3 到 5 个字符', trigger: 'blur' }
]
}
required: true, 是否为必填项
message: ‘error’, 提示信息
trigger: ‘blur’,触发事件 change,mouseon…
官方文档:http://www.axios-js.com/zh-cn/docs/vue-axios.html
1、【安装axios依赖】
npm install --save axios vue-axios
2、【在main.js里面引入axios】
import Vue from 'vue' import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios)
3、【你可以按照以下方式使用:】
Vue.axios.get(api).then((response) => {
console.log(response.data)
})
this.axios.get(api).then((response) => {
console.log(response.data)
})
this.$http.get(api).then((response) => {
console.log(response.data)
})
3.3.2 全局的axios配置
axios.defaults.baseURL = 'https://api.example.com'; // 设置请求的根路径 axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; // 认证授权码 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // post提交方式默认的头信息3.3.3 Axios封装的请求
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.options(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]])
前后端分离可以很好的实现代码的解耦和性能的提升,以上只是我最近接触的一些感悟与小结,要想真正的掌握,还需要不断地摸索学习。
- Vue
- Axios
- Element-UI
- SpringBoot
- …



