随着互联网的高速发展以及信息技术的不断升级,前后端分离已经逐渐曾为互联网项目开发的标准方式。在实际的开发工作中,前后端的接口测试占据了大量的前端开发人员的大量时间。
为了实现前端和后端人员的开发独立,达到专注自己的核心
把前端和后端独立开发,放在不同的服务器上,独立部署运行。这就是两个工程,这样,前后端的工作人员可以通过团队间的协商,约定一致的交互接口,实现同步开发。
这样。前端小伙伴只需要关注页面的样式和动效等展示效果,后端小伙伴就只需要关注数据的获取与业务逻辑的处理。
提高团队见的开发效率,分工更加明确化。
前台页面的修改再也不需要考虑后台的事情,开发更加灵活。前端不需要再向后端程序猿提供页面模板。
彻底脱离了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
Vue项目创建方式有多种,但是前提是必须要先安装好Node.js,关于Node的安装,如果没有安的话,自行baidu搜索。
1️⃣ 方式一:
通过Vue ui来创建vue项目
我们调出黑窗口(win+R),在窗口中敲入vue ui,进入到vue的可视化图形管理页面进行创建vue项目
我取消了git,选择包管理器为npm,并且为项目起一个名字,点击下一步
选择手动配置,点击下一步
取消勾选linter,并选中Router和Vuex版本管理,点击下一步
选择vue版本为2.x,点击创建
点击创建项目,不保存为预设,等待进度条加载需要加载包
2️⃣ 方式二:
通过黑窗口 vue命令的方式安装。自行百度,操作和用vue ui步骤是一样的。
vue create 项目名称 -- 创建项目
cd 项目路径 -- 进入到项目目录下
npm run serve -- 启动项目
使用Spring提供的创建平台创建
注意项目所需要使用的依赖有:
并完成后端项目框架的搭建
创建 一个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);
实现一个简单的CURD操做
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("bookService")
private BookService bookService;
@GetMapping("/queryAll")
public List<Book> queryAll(){
return bookService.queryAll();
}
@PostMapping("/queryByPage/{pageNum}/{pageSize}")
public PageInfo<Book> queryByPage(@PathVariable("pageNum") Integer pageNum,
@PathVariable("pageSize") Integer pageSize){
PageInfo<Book> pageInfo = bookService.queryByPage(pageNum, pageSize);
List<Book> 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 "添加失败!请重新添加";
}
}
/**
* 按照id查询图书信息
*/
@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";
}
}
}
解决跨域问题主要分为两个方向:1、前端解决;2、后端解决
在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'
}
}
全局配置是需要单独写一个配置文件类,在该配置类上实现WebMvcConfiguration
接口,然后实现接口里面的方法addCorsMappings
allowedOriginPatterns
也表示支持的域 一般用于SpringBoot2.6.x之后的版本
/**
* @author weiyongpeng
* DATA 2022/6/22 16:28
* @version 1.0
* @Request: 解决跨域问题 1、实现WebMvcConfigurer 2、配置跨域参数
*/
@Configuration
public class CrossConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置 映射为/** 所有8091端口下的所有服务映射,和所有的方法
registry.addMapping("/**") // 设置允许跨域请求的路由 url
//.allowedOrigins("*") //
.allowedOriginPatterns("*") // 设置允许跨域请求的域名
.allowedMethods("GET","HEAD","POST","PUT","DELETE") // 设置允许访问的请求方式
.allowCredentials(true) // 是否允许证书
.maxAge(3600) // 跨域允许时间
.allowedHeaders("*");
}
}
说明
:这里因为我是用的SpringBoot2.6以后的版本,如果使用allowOrigin会报错
局部配置是在类上或者方法上添加一个注解@CrossOrgin
|--node_module 本地项目的第三方依赖
|
|--public
|
|--src 开发目录 项目源码
| |
| |--assets 开发时候存放的一些静态资源
| |
| |--components 业务开发的组件
| |
| |--plugins 开发过程中安装的插件
| |
| |
| |-router 前端工程的路由,将其模块化,单独的拿出来
| | |
| | |-router.js 工程的路由配置
| |
| |-vuex vuex转态管理
| | |
| | |-store.js
| |
| |-App.vue 工程的入口文件,也是整个工程的根组件
| |-main.js 工程的入口文件,用以引入一些全局变量
| |-.gitignore 提交git仓库忽略的文件
| |-babel.config.js babel的一些配置
| |-package.json 依赖的第三方配置文件
| |-readMe.md 项目简单介绍
首先先下载安装Element-ui
【命令】
npm install --save element-ui
安装成功显示的效果如上所示:
全局引入Element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
官网:https://element.eleme.cn/#/zh-CN
用于布局的容器组件,方便快速搭建页面的基本结构:
:外层容器。
当子元素中包含 :顶栏容器。
:侧边栏容器。
:主要区域容器。
:底栏容器。
一般而言,我们大多数的后台管理系统,布局大多选择使用
侧边栏,头部区和脚步区
的布局方式即可,在开发中根据需要选择。
我们后端程序猿使用这种组件,只需要复制粘贴使用即可,接下来,我们就是需要他如何使用:
用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
el-table:表格标签
:stripe="true"
:斑马线设置:data="tableData"
:表格数据来源el-table-column:表格中的列
fixed
:固定列:支持的参数”left“和”right“prop
:列的名称,与data中的键名保持一致label
:显示的数据名称由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据
不同的是,Element-ui里自带了表单的校验
只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。
<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="author">
<el-input v-model="ruleForm.author">el-input>
el-form-item>
<el-form-item>
<el-button type="primary" :plain="true" @click="submitForm('ruleForm')">立即添加el-button>
<el-button @click="resetForm('ruleForm')">重置表单el-button>
el-form-item>
el-form>
el-form :
为表单的标签
:model
:绑定表单数据 。:
是v-bind
数据双向绑定标签的简写形式,不会的可以去看看vue:rules
: 为绑定检验规则的数据el-form-item:
为表单项的标签
prop
: prop属性绑定规则校验label
:label属性设置表单项的名字…
Element UI 后台管理系统主要的标签:
el-container:
构建整个⻚⾯框架。el-aside:
构建左侧菜单。el-menu:
左侧菜单内容,常⽤属性:
:default-openeds:
默认展开的菜单,通过菜单的 index 值来关联。:default-active:
默认选中的菜单,通过菜单的 index 值来关联。el-submenu:
可展开的菜单,常⽤属性:
index:
菜单的下标,⽂本类型,不能是数值类型。
template:
对应 el-submenu 的菜单名。i:
设置菜单图标,通过 class 属性实则。
el-menu-item:
菜单的⼦节点,不可再展开,常⽤属性:
index:
菜单的下标,⽂本类型,不能是数值类型。明白了这些,我们将官网上提供的一个模板的代码,粘贴到我们项目的App.vue页面上。
【步骤】:
标签添加 router 属性。
在⻚⾯中添加 标签,它是⼀个容器,动态渲染你选择的 router。
标签的 index 值就是要跳转的 router
如果安装路插件时没有自动的导入Router,需要我们手动引入
import Router from 'vue-router'
Vue,use(Router)
导入所有需要的页面组件,这些组件即为项目所需的页面,为每一个页面都配置上路由
const Index = () => import('../views/Index.vue');
const BookManage = () => import('../components/BookManage')
const AddBook = () => import('../components/BookAdd')
const Tag = () => import('../components/Tag')
const BookUpdate = () => import('../components/BookUpdate')
const Demo =()=>import('../components/demo.vue')
使用Router搭建左侧的导航结构(这里搭建的是一个二级目录),三级四级同理
export default new Router({
routes: [
{
path: "/",
name: "图书管理",
component: Index,
show: true,
redirect: "/BookManage",
iconCls: 'el-icon-menu',
children: [
{
path: "/BookManage",
name: "查询图书",
component: BookManage,
iconCls: 'el-icon-search',
},
{
path: "/BookAdd",
name: "添加图书",
component: AddBook,
iconCls: 'el-icon-circle-plus',
}
]
},
{
path: '/',
component: Index,
name: '人员管理',
show: true,
iconCls: 'el-icon-s-custom',
children: [
{
path: '/Tag', name: 'Tag', component: Tag,
iconCls: 'fa fa-address-card',
},
{
path: '/Demo', name: 'Demo', component: Demo,
iconCls: 'fa fa-address-card',
}
]
}
]
})
路由配置完毕后,还需要再App.vue,即使用Elementui组件的页面里进行循环遍历其配置的参数,实现匹配。
<el-aside width="200px">
<el-row class="tac">
<el-col :span="24">
<el-menu router :default-openeds="['0','1']">
<el-submenu v-for="(item,index) in $router.options.routes" :index="index+''" v-if="item.show">
<template slot="title"><i :class="item.iconCls">i>{{item.name}}template>
<el-menu-item v-for="(item2,index2) in item.children" :index="item2.path"
:class="$route.path==item2.path?'is-active':''"><i :class="item2.iconCls">i>{{item2.name}}el-menu-item>
el-submenu>
el-menu>
el-col>
el-row>
el-aside>
❓
如何获取到路由页的参数呢:
这里需要介绍两个东西
- $route:是用来获取路由信息的
- $router:是用来操作路由的
【参考】:https://blog.csdn.net/xunfengZ/article/details/109670979总结:
$router.options.routes可以拿到初始化的配置的路由规则
$route 可以拿到当前的路由信息 包括路由路径,参数等
要想点击左侧的导航栏后在内容区域显示,就需要在el-main中添加
表格的使用就是需要拷贝官网的代码,找一款自己喜欢的样式,根据上面的介绍的来修改即可,接下来我们需要做的就是把后端获取的数据加载到这个表格里面即可。
npm install --save axios
在main.js里面全局导入Axios,并配置全局的BaseURL参数
// 导入Axios组件
import axios from 'axios'
// 配置axios
axios.defaults.baseURL='http://localhost:8091/'; /*项目根路径*/
/*将Axios加载到Vue的原型链中 以后在任何的.vue文件中使用axios,只需要this.$axios.xxx即可*/
Vue.prototype.$axios = axios;
- created:在模板渲染成Html之前调用,通常初始化某些值的时候使用,渲染成视图
- mounted:在模板渲染成html之后调用,通常是初始化页面之后,在对html的dom进行操做
@PostMapping("/queryByPage/{pageNum}/{pageSize}")
public PageInfo<Book> queryByPage(@PathVariable("pageNum") Integer pageNum,
@PathVariable("pageSize") Integer pageSize){
PageInfo<Book> pageInfo = bookService.queryByPage(pageNum, pageSize);
List<Book> 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;
}
<el-pagination
background
layout="prev, pager, next"
page-size="5"
:total="total"
@current-change="page">
el-pagination>
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)
})
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提交方式默认的头信息
前后端分离可以很好的实现代码的解耦和性能的提升,以上只是我最近接触的一些感悟与小结,要想真正的掌握,还需要不断地摸索学习。