1.将应用的前后端代码分开写
总结:请后端分离就是将一个单体应用拆分成两个独立的应用。前端应用于后端应用通过json格式的数据进行交互
springboot:后端应用开发
vue:前端应用开发
el-container:构建整个框架
el-aside:构建左侧菜单
el-menu:构建左侧菜单内容,常用属性
:default-openeds 默认展开菜单,通过菜单的index值关联
:default-active 默认选中的菜单,通过菜单的index值关联
4.el-submenu:可展开的菜单。常用属性
index:菜单的下标,文本类型,不能是数值类型
5.template:对应el-submenu的菜单名
6.i标签:设置菜单图标,通过class属性设置
el-icon-message
el-icon-menu
el-icon-setting
7.el-menu-item:菜单的子节点,常用属性
index:菜单的下标,文本类型,不能是数值类型
导航一
导航二
定义rules对象,在rules对象中设置表单各个选项的校验规则,具体语法如下
rules: {
name: [
{ required: true, message: '请输入书籍名称', trigger: 'blur' },
{ min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
]
}
//给rules里面的name选项设置校验规则,name对应标签的prop属性
//required: true 是否为必填项
// message: '请输入书籍名称' 提示消息
//trigger: 'blur' 触发3事件,失去焦点
{{item.name}}
{{item2.name}}
index.js路由配置
routes:[
{
path: '/',
name:'书籍列表',
component: Container,
redirect:"/page1",
children:[
{
path: '/page1',
name:'添加书籍',
component: page1
},
{
path: '/page2',
name:'修改用户',
component: page2
}
]
},
{
path: '/',
name: '课程管理',
component: Container,
children: [
{
path: '/page3',
name: '课程查看',
component: page3
},
{
path: '/page4',
name: '课程添加',
component: page4
}
]
}
]
扩展:若index.js中配置了一些必须要的路由但是侧边栏并不需要这些路由时,可以在路由里添加一个属性,通过v-if来决定是否需要展示
侧边栏具体效果:
3.展示数据UI
修改
删除
展示数据UI的form表单通过:data=“tableData”,与data()里面的tableData动态绑定了
分页条的total属性与data里面的total动态绑定,同时点击下一页时触发了一个点击事件,从而达到页面切换效果
界面展示:
4.添加页面UI
提交
重置
添加页面实现了数据的校验,以及良好的数据提示页面,给用户良好的体验
5.修改页面UI
提交
重置
因为直接从前端获取的数据不安全,容易被篡改,所以数据统一从数据库中查询出来,展示到页面之中,同时修改界面也有良好的用户体验
界面展示:
6.删除功能:
删除
deleteBook(row) {
const _this = this
this.$confirm('是否确定删除《' + row.name + '》', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
_this.$axios.delete('http://localhost:8181/book/delete/' + row.id).then(function (response) {
// _this.$router.push('/page1')
window.location.reload();//动态刷新页面
}),this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
删除操作给用户足够的反应时间以及误操作的取消操作
package com.sunset.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CrosConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")
.allowedMethods("*")
.allowedOriginPatterns("*")
.allowCredentials(true);
}
}
2.实体类定义
package com.sunset.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;@Entitypublic class Book { @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; }}
3.dao层定义(适用springboot jpa操作数据库)
package com.sunset.repository;import com.sunset.entity.Book;import org.springframework.data.jpa.repository.JpaRepository;public interface BookRepository extends JpaRepository<Book,Integer> {//泛型,第一个代表对应的实体类,第二个泛型代表主键}
4.service层:因为业务较为简单,所以没有写service层
5.controller层
package com.sunset.controller;import com.sunset.entity.Book;import com.sunset.repository.BookRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Pageable;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping("/book")public class BookController { @Autowired private BookRepository bookRepository; @GetMapping("/findAll/{page}/{size}") public Page<Book> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size){ Pageable pageable = PageRequest.of(page-1,size); return bookRepository.findAll(pageable); } @PostMapping("/save") public String save(@RequestBody Book book){ Book result = bookRepository.save(book); if(result!=null){ return "success"; }else return "error"; } @GetMapping("/findById/{id}") public Book findById(@PathVariable("id") Integer id){ return bookRepository.findById(id).get(); } @PutMapping("/update") public String update(@RequestBody Book book){ Book result = bookRepository.save(book); if(result!=null){ return "success"; }else return "error"; } @DeleteMapping("/delete/{id}") public String delete(@PathVariable("id") Integer id){ bookRepository.deleteById(id); return "success"; }}
controller层统一采用restful风格编程
采用vue集成的axios进行数据传输,与通信
egg:修改书籍信息模块:
修改 edit(row) { this.$router.push({ path:'/page3', query:{ id:row.id } }) }
created() { const _this = this this.$axios.get("http://localhost:8181/book/findById/"+this.$route.query.id).then(function (response) { console.log(response.data) _this.ruleForm = response.data }) // alert(this.$route.query.id) } }
提交
submitForm(formName) {
const _this = this
this.$refs[formName].validate((valid) => {
if (valid) {
_this.$axios.put('http://localhost:8181/book/update',_this.ruleForm).then(function (response) {
// console.log(response)
if(response.data=='success'){
_this.$alert('《'+_this.ruleForm.name+'》修改成功', '消息', {
confirmButtonText: '确定',
callback: action => {
_this.$router.push('/page1')
}
});
// _this.$router.push('/page1')
// _this.$message('添加成功')
}
})
// alert('submit!');
console.log(_this.ruleForm)
} else {
console.log('error submit!!');
return false;
}
});
}
该前后端分离项目相较之下还是比较简单的,但实现了基本的CRUD操作,前端通过VUE,ElementUI进行架构,后端通过springboot,基于restful的数据接口进行对接,实现了前后端的解耦合