前后端分离开发流程
试验环境:
windows7+16G内存+Idea2018+mysql5.6
后端使用springBoot
前端使用的是vue
jdk1.8
vue4.5.2
npm 6.13.4
相关准备
对于vue的简单熟悉VUE学习笔记
数据库建表:数据库的学习笔记
创建前端项目错误解决
错误1:vue ui不起作用
控制台输入命令vue ui不起作用
vue ui 创建vue的项目
vue -h 查看vue命令的参数
vue -V 查看vue的版本
vue ui命令3.0以上才有作用因此需要使用更新命令的操作更新版本。
npm i -g @vue/cli 有可能失败可以使用国内镜像
cnpm i -g @vue/cli
vue内嵌一个服务器:
使用命令: npm run serve 启动应用程序
错误2:v-for
使用vue的v-for时可能会出错:
Elements in iteration expect to have ‘v-bind:key’ directives
这个是由于仅使用v-for是不够的因此需要加入:key = “item.id”关键字
前端的错误
Book.vue?b0f7:49 Uncaught (in promise) TypeError: Cannot set property ‘books’ of undefined
表示当前指向的某个对象的this关键字没有books属性,一般是因为回调函数中访问vue对象产生的错误,回调函数中的this表示的是回调函数的对象不是vue对象,因此不能访问vue对象的相关数据。
//回调函数外可以定义全局变量,再将当前的this对象保留下来
created(){
const _this = this
axios.get('http://localhost:8181/book/findById/'+this.$route.query.id).then(function(resp){
_this.ruleForm = resp.data
})
}
前后端分类项目的说明:
实现一个图书管理的增删改查(从别人的程序中学习的),自己练习了一个人员管理的页面设计与数据交互。
前端给后端发送的数据是一个json数据格式,后端解析后实现数据库操作,后端将数据封装成json交给前端的页面展示。
vue 集成Element ui
安装方式1:重新创建项目,安装插件
安装方式2:如果浏览器中安装失败使用命令进行安装
cnpm install –save element-ui
或者
npm i element-ui -S
前端数据简单测试
前端自定义数据进行测试
编号
图书名称
作者
{{item.id}}
{{item.name}}
{{item.author}}
{{msg}}
跨域问题的解决
后端解决方案:
//springBoot中配置类,对前端的请求进行处理
@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("*");
}
}
前端布局
elementui的布局实例:
el-container: 页面的布局容器页面布局的整体框架
el-aside:构建左侧的菜单
el-menu: 左侧菜单的内容
:default-openeds属性,表示菜单属性默认展开
:default-active属性,表示菜单属性默认选中某个节点
el-submenu 可展开的菜单
index 菜单的下标,文本类型,不能是数值类型
template 对应el-submenu的菜单名
i标签:设置菜单图标,通过class属性设置官方网站的icon设置
el-menu-item:菜单的子节点,不可展开
属性index,子菜单下标
通过vue的router构建前端的项目框架菜单
例如:
导航栏1
子页面1
子页面2
导航栏2
子页面1
子页面2
菜单与route绑定
1.给
2.在页面中添加router-view标签,是一个容器,可以动态渲染router选择
3.
前后端交互组件axios
vue使用rust访问后端数据需要安装一个组件axios,使用命令安装axios
vue add axios
安装完后项目中显示plugins/axios.js,表示安装完成。
前后端数据交互组件安装完成后,前端在created方法中调用组件,传递url后端的rusrful风格,接受的数据在前端的页面显示。
Element UI表单
表单校验,表单中定义rules对象,设置对象的规则
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<!--使用prop表示指定与之相应的数据规则-->
<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>
<!--js中定义数据规则,在表单中设置:rules属性,以下是两个文本框的规则实例
required:表示是否为必选项
message:提示信息
trigger:出发事件
-->
<script>
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
author: [{required: true, message: '请输入活动名称', trigger: 'blur' },
{min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur'}]
}
</script>
Element UI表格组件
<template>
<div>
<!--:model="ruleForm" 绑定数据格式 :rules="rules" 校验规则-->
<el-form :model="ruleForm" style="width: 60%" :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" @click="submitForm('ruleForm')">提交</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
<!-- <el-button @click="test()">测试按钮</el-button> -->
</el-form-item>
</el-form>
</div>
</template>
前端的数据绑定
<script>
export default {
//前端数据校验
data() {
return {
ruleForm: {
name: '',
author: '',
},
rules: {
name: [
{ required: true, message: '图书名不能为空', trigger: 'blur' },
{ min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur' }
],
author: [{required: true, message: '作者名不能为空', trigger: 'blur' },
{min: 2, max: 10, message: '长度在2 到 5 个字符', trigger: 'blur'}]
}
};
},
methods: {
//前后端数据信息交互
submitForm(formName) {
const _this = this
this.$refs[formName].validate((valid) => {
if (valid) {
axios.post('http://localhost:8181/book/save',_this.ruleForm).then(function(msg){
if(msg.data=='success'){
_this.$alert('《'+_this.ruleForm.name+'》成功添加', '添加信息', {
confirmButtonText: '确定',
callback: action => {
_this.$message({
type: 'info',
message: `action: ${ action }`
}) }
});
_this.$router.push('/BookManage')
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script>
后端项目
配置文件
配置数据库信息,配置JPA访问数据,配置端口信息
spring:
datasource:
url: jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 123
driver-class-name: com.mysql.cj.jdbc.Driver
##配置jpa的数据库格式化、显示数据库语句
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
server:
port: 8181
配置项目的依赖,spring-data、springboot、数据库连接驱动、单元测试、lombok等相关依赖
<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>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>
数据实体层(Entity)
@Entity
@Data
public class Book {
//使用主键注解Id,注解GeneratedValue表示主键生成策略
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String author;
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getName() { return name; }
public void setName(String name) {this.name = name;}
public String getAuthor() {return author;}
public void setAuthor(String author) { this.author = author;}
}
数据仓库层(dao)
//只需要定义接口实现JpaRepository类即可使用其中的增删改查方法,传入的参数为实体类对象以及注解类型
public interface BookRepository extends JpaRepository<Book,Integer> {
}
控制层(controller)
控制层获取前端的请求,使用RustFul风格的可以后台定义分页查询、全部数据查询、根据主键查询、新增数据、删除数据、修改数据
查询请求 @GetMapping
新增请求 @PostMapping
修改请求 @PutMapping
删除请求 @DeleteMapping
从路径中获取相关的信息 @PathVariable
将json对象转换成java实体类对象 @RequestBody
@RestController
@RequestMapping("/book")
public class BookHandler {
@Autowired
private BookRepository bookRepository;
//插叙Book数据库中的数据,分页显示,传入的参数当前页和每页显示的条数
@GetMapping("/findAll/{page}/{size}")
public Page<Book> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
PageRequest request = PageRequest.of(page-1,size);
return bookRepository.findAll(request);
}
//查询所有的数据,一般不使用,由于查询出的数据太多
@GetMapping("/findAll")
public List<Book> findAll(){
return bookRepository.findAll();
}
@GetMapping("/findById/{id}")
public Book findById(@PathVariable("id") Integer id){
return bookRepository.findById(id).get();
}
//保存数据,返回成功或失败信息
//RequestBody将json对象转换成java的对象
@PostMapping("/save")
public String save(@RequestBody Book book){
Book result = bookRepository.save(book);
if(result != null){
return "success";
}else{
return "error";
}
}
@PutMapping("/update")
public String update(@RequestBody Book book){
Book result = bookRepository.save(book);
if(result != null){
return "success";
}else{
return "error";
}
}
@DeleteMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") Integer id){
bookRepository.deleteById(id);
}
}
自定义启动图案
springBoot可以自定义启动的图案,从源码中读取信息可以创建一个banner.txt的文件设置自己的图案:
public static final String BANNER_LOCATION_PROPERTY_VALUE = "banner.txt";
开发时使用:
// _oo0oo_
// o8888888o
// 88" . "88
// (| -_- |)
// 0\ = /0
// ___/'---'\___
// .' \\\| |/// '.
// / \\\||| : |||/// \
// / _ ||||| -:- ||||| - \
// | | \\\\ - //// | |
// | \_| ''\---/'' |_/ |
// \ .-\__ '-' __/-. /
// ___'. .' /--.--\ '. .'___
// ."" '< '.___\_<|>_/___.' >' "".
// | | : '- \'.;'\ _ /';.'/ - ' : | |
// \ \ '_. \_ __\ /__ _/ .-' / /
// ====='-.____'.___ \_____/___.-'____.-'=====
// '=---='
//
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// 佛祖保佑 永无BUG
使用postman工具测试
可以参照别人的博客postman的使用
1.在Chrome输入地址:chrome://extensions/
2.将压缩包直接拖拽至Chrome中
3.运行在Chrome输入地址:chrome://apps可以从我的百度网盘下载并按照以上步骤进行使用
测试查询的结果如下
后端项目的结构
前端项目的结构