怎样用springboot开发cs_SpringBoot开发简单的前后端分离系统

本文详细介绍了如何使用SpringBoot开发一个简单的前后端分离系统,包括Vue项目的创建、配置、数据交互以及与SpringBoot后端的接口对接。通过实例展示了Vue组件的创建、数据绑定、路由设置,以及SpringBoot的数据库操作、接口开发和跨域配置。最终实现了动态数据加载、分页查询、数据添加、修改和删除功能。
摘要由CSDN通过智能技术生成

自学Java 水平比较低 放弃春招准备全力秋招

第一次学习项目 分享一下 适合小白

安装node和vue

首先安装node.js,下载地址:node.js

下好后.exe直接安装就行了,然后在命令行通过node -v查看是否安装成功

然后初始化,通过node init完成,一路按回车就行

然后设置一个镜像点,不然可能因为网速问题一直无法成功

之后下载vuenpm install -g @vue/cli

等待一段时间后,vue -V查看是否安装成功

创建vue项目

通过vue ui命令

然后访问localhost:8000这个地址

创建新工程

下一步,手动

下一步打开router和vuex,关闭代码校验

下一步,选中使用历史记录,然后完成,创建项目,不保存预设,稍微等待几分钟

进行测试,点击任务,serve,启动,然后输出,观察url地址

访问localhost:8080 ,没有问题

然后命令行CTRL+c退出,关闭服务

IDEA导入VUE工程

直接import刚才的工程就行,一路next和finish

然后需要安装一个vue的插件,如果网不好就用手机热点,多试几次。。

大概试了1个多小时,安装成功后,有一个app.vue

在命令行通过npm run serve启动

通过ctrl+c终止

router-link标签表示映射的视图,app.vue是主视图,可以跳到home和about

映射关系配置在router目录下的index.js

创建SpringBoot项目

选择组件

这里我下载不下来2.2.6,使用以前下载的2.2.1.RELEASE

创建数据库表

数据库叫stock,表叫stock,有四个字段表示id,股票名,当前价格和涨跌幅比率

配置文件

在resources下新建一个application.yml,配置你自己的数据库信息

创建Vue视图

在vue工程创建一个Vue组件,叫Stock

template就是html,script就是js,style就是css

编写假数据进行一个简单的测试

在index.js中配置路由

命令行启动

访问localhost:8080/stock,成功了

增加两组测试数据

接收结果

Vue是动态加载的,此时再看刚才的页面

更好的写法是通过循环来返回结果

创建实体类

回到spring boot工程,创建股票对应实体类

@Entity

@Data

public class Stock {

@Id

private Integer id;

private String name;

private Double price;

private Double rate;

}

创建操作实体类的接口

只需要基础JpaRepository即可,第一个参数是实体类类型,第二个参数是主键类型

public interface StockRepository extends JpaRepository {

}

在接口处右键点击goto->test,创建一个test测试类

@SpringBootTest

class StockRepositoryTest {

@Autowired

private StockRepository stockRepository;

@Test

void findAll(){

System.out.println(stockRepository.findAll());

}

}

插入两行测试数据

运行

测试查询

新建一个controller包,创建一个Controller

@RestController//声明基于rest的控制器

@RequestMapping("/stock")//根url配置

public class StockController {

@Autowired//自动注入

private StockRepository stockRepository;

@GetMapping("/findAll")//get请求所有数据

public List findAll(){

return stockRepository.findAll();

}

}

启动springboot

访问localhost:8181/stock/findAll,OJBK

替换假数据

之前我们Vue里的数据是假的,是我们自己加入测试的,不是数据库中的,所以我们现在要让前端的数据请求后端的。

安装axios

回到Vue项目,在控制台CTRL+c停止服务,输入vue add axios,添加该服务

等待一段时间,安装成功

编写请求

我们希望每次刷新页面时都会加载新数据,写到初始化函数中,还是要写到export default代码块中:

then里面的回调函数表示输出当前获取的结果,由于我们的Vue项目在8080,而后端的SpringBoot在8181,因此存在一个跨域问题

解决跨域问题

回到SpringBoot项目

创建一个config包,一个配置类,需要实现WebMvcConfigurer接口,并重写addCorsMappings方法,允许任何跨域请求

@Configuration

public class CorsConfig implements WebMvcConfigurer {

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

.allowedOrigins("*")

.allowedMethods("GET","POST","HEAD","PUT","DELETE","OPTIONS")

.allowCredentials(true)

.maxAge(3600)

.allowedHeaders("*");

}

}

然后重新启动SpringBoot服务器,此时我们刷新刚才的vue视图,打开F12开发者模式,在其中可以发现请求数据成功了,在console中可以看到

然后将测试的输出语句改为替换语句,将请求结果的值赋值给stocks股票数组,created里axios代码块外的this是vue对象,而axios里的this是回调函数,所以我们通过中间变量_this存储代码块外面的this,也就是vue对象,然后才能获取stocks。

此时,已经显示的是数据库中的数据,35.42,而不是我们写的假数据,34.12

Element UI

按之前的步骤,重新创建一个Vue工程,之后,搜索element ui

选中并安装

安装成功

待Vue项目创建成功后,打开IDEA,导入Vue项目

如果打开后有这个el-button就代表成功了

修改App.Vue的内容为以下内容:

导航一

分组一

选项1

选项2

选项3

选项4

选项4-1

导航二

分组一

选项1

选项2

选项3

选项4

选项4-1

导航三

分组一

选项1

选项2

选项3

选项4

选项4-1

查看

新增

删除

王小虎

.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)

}

}

};

再刷新首页

其中的一些标签含义如下:

el-container 构建整个页面框架

el-aside 构建左侧菜单

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

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

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

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

index:菜单下标,文本类型,不能是数值类型

template:对应el-submenu的菜单名

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

el-menu-item:菜单的子结点,不可再展开,常用属性

index:菜单下标,文本类型,不能是数值类型

通过router动态构建左侧菜单

在view下创建四个Vue组件,分别为PageOne/Two/Three/Four

只需要修改每个h1标签中的数字即可

在index.jsp中,先导入四个组件

修改映射

将App.vue的main标签中的内容替换为

此时的效果

接着修改index.jsp中的配置

const routes = [

{

path:"/",

name:"导航1",

component:App,

children:[

{

path:"/pageOne",

name:"页面1",

component:PageOne

},

{

path:"/pageTwo",

name:"页面2",

component:PageTwo

}

]

},

{

path:"/navigation",

name:"导航2",

component:App,

children:[

{

path:"/pageThree",

name:"页面3",

component:PageThree

},

{

path:"/pageFour",

name:"页面4",

component:PageFour

}

]

}

]

此时的效果

修改el-aside标签中的内容

{{item.name}}

{{item2.name}}

此时的效果

最后,只留下aside和main部分

此时的效果

设置动态路由导航栏

App.vue里只保留一行router-view标签,把内容移到新创建的Index.vue

在index.js配置映射,将app替换为刚才创建的index,因为Vue里App.vue是基础视图,其他视图相当于都在它的基础之上显示

此时的效果

接下来实现通过点击左边的页面1234切换页面的功能:

给el-menu添加router属性

在页面添加router-view标签

设置el-menu-item的index值,即为跳转页面

此时的效果,选哪个就跳哪个

通过redirect属性设置访问loaclhost8080的默认页面

此时访问8080会默认跳到pageOne

但是没有选中效果,通过class属性指定,利用三面运算符,当route.path(浏览器url的地址)和item2.path(设置的路由地址)一样时,具有选中效果

此时具有选中效果

前后端分离开发数据对接

复制table代码

将pageOne.vue复制为以下表单代码

:data="tableData"

border

style="width: 100%">

fixed

prop="date"

label="日期"

width="150">

prop="name"

label="姓名"

width="120">

prop="province"

label="省份"

width="120">

prop="city"

label="市区"

width="120">

prop="address"

label="地址"

width="300">

prop="zip"

label="邮编"

width="120">

fixed="right"

label="操作"

width="100">

查看

编辑

export default {

methods: {

handleClick(row) {

console.log(row);

}

},

data() {

return {

tableData: [{

date: '2016-05-02',

name: '王小虎',

province: '上海',

city: '普陀区',

address: '上海市普陀区金沙江路 1518 弄',

zip: 200333

}, {

date: '2016-05-04',

name: '王小虎',

province: '上海',

city: '普陀区',

address: '上海市普陀区金沙江路 1517 弄',

zip: 200333

}, {

date: '2016-05-01',

name: '王小虎',

province: '上海',

city: '普陀区',

address: '上海市普陀区金沙江路 1519 弄',

zip: 200333

}, {

date: '2016-05-03',

name: '王小虎',

province: '上海',

city: '普陀区',

address: '上海市普陀区金沙江路 1516 弄',

zip: 200333

}]

}

}

}

复制分页代码

创建一个div标签,将刚才的table放进去,再加入分页代码

background

layout="prev, pager, next"

:total="1000">

此时效果

创建假数据

table中的数据来自data,先修改data数据

修改table数据,prop就是data中的属性,label是表单中的列名

此时效果

修改分页

每页3条记录,一共30条10页,点击事件为page方法

page-size前面要和total一样加上冒号,当时漏掉了

page(currentPage){

switch (currentPage) {

case 1:

this.tableData=[{

id: 1,

name: '科技股',

price: 45.43,

rate: +1.57

}, {

id: 2,

name: '教育股',

price: 35.22,

rate: +0.19

}, {

id: 3,

name: '石油股',

price: 45.43,

rate: -4.61

}, {

id: 4,

name: '餐饮股',

price: 17.43,

rate: -9.77

}];

break;

case 2:

this.tableData=[{

id: 4,

name: '科技股1',

price: 45.43,

rate: +1.57

}, {

id: 5,

name: '教育股2',

price: 35.22,

rate: +0.19

}, {

id: 6,

name: '石油股3',

price: 45.43,

rate: -4.61

}, {

id: 7,

name: '餐饮股4',

price: 17.43,

rate: -9.77

}];

break;

}

}

此时点击第二页会显示新的数据

实现分页查询

由于前端是分页显示,但是可以看到后端查询的数据是一次全部查出来,需要进行分页

先增加一点数据,然后查询,显示了全部

修改StockController中的方法,传入page和size,表示第几页,显示几条记录

如果第一页就是0,page=要显示的页-1

@GetMapping("/findAll/{page}/{size}")//get请求所有数据

public Page findAll(@PathVariable("page")Integer page, @PathVariable("size")Integer size){

PageRequest pageRequest=PageRequest.of(page,size);

return stockRepository.findAll(pageRequest);

}

重启springboot,测试,传入0和3

查询第二页就传1和3

跟之前一样,先安装axios

替换为真数据,跟之前一样,还是通过create参数和_this的赋值

此时默认显示前3条

修改pageOne为以下代码

:data="tableData"

border

style="width: 100%">

fixed

prop="id"

label="股票id"

width="150">

prop="name"

label="股票名"

width="120">

prop="price"

label="股票当前价格"

width="120">

prop="rate"

label="股票涨跌幅"

width="120">

fixed="right"

label="操作"

width="100">

查看

编辑

background

layout="prev, pager, next"

:page-size="pageSize"

:total="total"

@current-change="page">

export default {

methods: {

handleClick(row) {

console.log(row);

},

page(currentPage){

const _this=this;

axios.get('http://localhost:8181/stock/findAll/'+(currentPage-1)+'/3').then(function (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/stock/findAll/0/3').then(function (resp) {

console.log(resp);

_this.tableData=resp.data.content;

_this.pageSize=resp.data.size;

_this.total=resp.data.totalElements;

})

}

}

此时成功实现分页

添加数据

在前端添加数据

修改index.js,把之前的pageOne改为stockQuery,pageTwo改为stockUpdate

现在的效果

接下来开始完成添加数据的功能,将stockUpdate.vue修改为以下内容

model对象绑定数据,rules对象校验表单

添加

重置

export default {

data() {

return {

ruleForm: {

name: '',

price: '',

rate: '',

},

rules: {

name: [

{ required: true, message: '请输入名称', trigger: 'blur' },

],

price: [

{ required: true, message: '请输入价格', trigger: 'change' }

],

rate: [

{required: true, message: '请输入涨跌幅', trigger: 'change' }

]

}

};

},

methods: {

submitForm(formName) {

//_this表示当前vue对象

const _this=this;

this.$refs[formName].validate((valid) => {

if (valid) {

alert('submit!');

} else {

return false;

}

});

},

//重置表单

resetForm(formName) {

this.$refs[formName].resetFields();

}

}

}

当前效果

接下来需要写后台保存数据的代码

在后台添加数据

给id先加上自增注解

在controller中增加接口

@PostMapping("/save")//post请求提交数据

public void save(@RequestBody Stock stock){

stockRepository.save(stock);

}

重启SpringBoot,回到Vue项目,添加提交逻辑

测试,输入数据

点击添加,再查询数据库

前端也可以即时查询

优化提示效果

使用message方法

此时添加会弹出提示框

添加成功后回跳查询页

submitForm(formName) {

const _this=this;

this.$refs[formName].validate((valid) => {

if (valid) {

axios.post('http://localhost:8181/stock/save',this.ruleForm).then(function (resp) {

_this.$alert(_this.ruleForm.name, '添加成功', '消息',{

confirmButtonText: '确定',

callback: action => {

}

});

//回跳

_this.$router.push('/StockQuery');

})

} else {

return false;

}

});

}

会提示添加成功,并回跳查询页面

修改和删除数据

这里老师的代码有点问题,还需要做如下调整:

App.vue和Index.vue

把Index.vue和App.vue的template里的内容互换

配置index.js

将之前的StockUpdate改名StockAdd,新创建一个StockUpdate,在index.js配置

修改查询页

当点击修改时,将股票的行号传过去

修改StockUpdate

添加

重置

export default {

data() {

return {

ruleForm: {

name: '',

price: '',

rate: '',

},

rules: {

name: [

{ required: true, message: '请输入名称', trigger: 'blur' },

],

price: [

{ required: true, message: '请输入价格', trigger: 'change' }

],

rate: [

{ required: true, message: '请输入涨跌幅', trigger: 'change' }

]

}

};

},

methods: {

submitForm(formName) {

const _this=this;

this.$refs[formName].validate((valid) => {

if (valid) {

axios.post('http://localhost:8181/stock/save',this.ruleForm).then(function (resp) {

_this.$alert(_this.ruleForm.name, '添加成功', '消息',{

confirmButtonText: '确定',

callback: action => {

}

});

_this.$router.push('/StockQuery');

})

} else {

return false;

}

});

},

//重置表单

resetForm(formName) {

this.$refs[formName].resetFields();

},

},created() {

alert(this.$route.query.id);

}

}

先进行简单测试,例如点击第一行

弹出1

然后跳了过来

提供根据id查询接口

在Springboot的controller增加方法

@GetMapping("/findById/{id}")//get请求单个数据

public Stock findById(@PathVariable("id")Integer id){

return stockRepository.findById(id).get();

}

简单测试:

没有问题,回到StockUpdate.vue的created方法

此时点击修改按钮,会自动查询显示现在的最新值,为了显示id列,增加一段标签

增加id属性,设置为只读

此时会显示id

修改功能

先把按钮改为修改

成功

提供修改接口,之后重启SpringBoot服务器

@PutMapping("/update")//put请求修改数据

public void update(@RequestBody Stock stock){

stockRepository.save(stock);

}

只需要修改这三处

测试,给名字加上test

成功

增加删除点击事件del

增加删除接口del

@DeleteMapping("/deleteById/{id}")

public void delete(@PathVariable("id")Integer id){

stockRepository.deleteById(id);

}

然后重启服务器

调用接口

回到Vue项目

测试:

成功

如果希望删除后可以刷新,使用window.location.reload

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值