1. 前言
前后端分离模式,可以让后端和前端开发人员致力于自己擅长的领域,且可以让前端和后端业务逻辑高度解耦合。本文从一个简单的案例入手,讲解使用 spring boot
和vue3
如何实现前后端的分离。
前后端分离有2
种模式:
- 逻辑分离:在一个项目中的前后分离。项目整体架构还是
MVC
模式,适合于小型项目。 - 物理分离:独立的前后端项目分离。因是不同项目,会涉及远程调用等问题,适合于中、大型项目。后端项目仅是
API
提供者,可以服务于不同平台的前端项目,如网页版、微信小程序版的前端项目。
本文将使用 Spring Boot、Vue3、Elemnet Plus
分别构建这2
种分离模式。
无论使用哪一种分离模式,其后端API
都是一样的。所以,本文先搭建后端服务项目。
2. Spring Boot API
后端项目也称为服务器端,以提供API
为主,数据的应用以及显示由前端负责。本文后端项目的开发工具为IDEA
,当然,你也可以选择其它开发工具,关系数据库系统为mysql
。
2.1 创建项目
打开 IDEA
。新建名为 MyBook
的 Spring Boot
项目。
选择spring boot
的版本2.7.12
,且选择如下的依赖包:
-
Spring Boot DevTools
。 -
LomBok
。 -
Spring Web
。 -
MyBatis Framework
。 -
MySql Driver
。
确认后,项目的初始结构如下图所示:
打开项目的application.properties
文件,配置项目的jdbc
基本信息。
#配置数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/bookstore?useUnicode=true&characterEncoding=UTF-8&serverTimezone=PRC
spring.datasource.username=root
spring.datasource.password=abc123
2.2 设计 API
本项目是一个基础MVC
架构项目,仅提供一个用于测试的API
,功能是用来显示所有的书本信息。
本项目采用由下向上的设计流程,先创建数据库,并设计book
表。
Tips:
mysql
数据库系统的安装过程这里就不单独讲解,数据库连接客服端使用Navicat Premium
。
数据库设计:
- 启动
mysql
服务,打开Navicat Premium
。创建名为bookstore
的数据库,以及在数据库中创建名为book
的数据库表,其字段结构如下:
字段名 | 类型 | 备注 |
|
| 主键、自动增长 |
|
| |
|
| |
|
|
- 表命名为
book
,并向表中插入2
条测试数据。
数据库设计好后,开始项目结构的搭建:因项目使用 mybatis jdbc
框架,故先构建mapper
层。
-
mapper
层。
新建 mapper
层前,先创建book
类。使用lombok
简化book
类的代码。
package com.gk.mybook.bean;
import lombok.*;
@Data
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Book {
private Integer bookId;
private String bookTitle;
private String bookAuthor;
private Double bookPrice;
}
新建 BookMapper
类:提供查询所有书籍的方法的声明。
package com.gk.mybook.mapper;
import com.gk.mybook.bean.Book;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface BookMapper {
List<Book> getAllBooks();
}
编写 SQL
语句:查询所有书籍。
SELECT book_id,book_title,book_author,book_price from book
sql
文件书写在 BookMapper.xml
文件中,此文件存储在项目的 resources
中。为了让 BookMapper
自动找到xml
文件,在resources
文件中创建com.gk.mybook.mapper
结构的目录结构。
Tips:也可能自定义其它位置。
至此,项目结构如下图所示:
-
BookService
层:业务层。
定义业层接口IBookService
层,为业务层声明功能。
package com.gk.mybook.service;
import com.gk.mybook.bean.Book;
import java.util.List;
/*
*书籍业务对象
*/
public interface IBookService {
List<Book> getBooks();
}
构建业务对象BookService
:实现IBookService
接口,依赖BookMapper
对象。
package com.gk.mybook.service.impl;
import com.gk.mybook.bean.Book;
import com.gk.mybook.mapper.BookMapper;
import com.gk.mybook.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookService implements IBookService {
@Autowired
private BookMapper bookMapper;
@Override
public List<Book> getBooks() {
return this.bookMapper.getAllBooks();
}
}
此时,项目结构如下图所示:
- 控制器层,并向外映射接口。
package com.gk.mybook.action;
import com.gk.mybook.bean.Book;
import com.gk.mybook.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/book")
public class BookAction {
@Autowired
private IBookService bookService;
@RequestMapping("/books")
List<Book> getBooks(){
return this.bookService.getBooks();
}
}
- 测试接口。为了简化操作,直接在浏览器中测试,启动项目之前,别忘记在启动类前面加
@MappScan
注解,其实新版本spring boot
可以省略此注解。
package com.gk.mybook;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = {"com.gk.mybook.mapper"})
public class MybookApplication {
public static void main(String[] args) {
SpringApplication.run(MybookApplication.class, args);
}
}
运行程序后,打开浏览器,在地址栏中输入http://localhost:8080/book/books
。如果能看到下面的结果,说明服务器搭建成功。
3. Vue Project
如上所说,前后分离有 2
种使用方式。
3.1 逻辑分离
直接在服务器项目的view
层的html
页面中使用vue
框架。
在后端项目的resources->static
目录中新建index.html
文件。在文件中引入Vue、Element plus、axios
依赖库。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>书籍</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-plus"></script>
<script src="https://unpkg.com/vue-router@4"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
项目结构如下图:
编写如下JS
代码,实现在页面中显示所有书籍信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>书籍</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-plus"></script>
<script src="https://unpkg.com/vue-router@4"></script>
</head>
<body>
<div id="app">
<h1>{{title}}</h1>
<el-table :data="books">
<el-table-column v-for="book in cols" :key="book.en"
:prop="book.en"
:label="book.cn"
show-overflow-tooltip align="center" width="160px">
<template #default="scope">
{{ scope.row[book.en] }}
</template>
</el-table-column>
</el-table>
</div>
<script>
const {createApp} = Vue
var app = createApp({
data() {
return {
title: "我的书籍",
cols: [{"en": "bookId", "cn": "编号"}, {"en": "bookTitle", "cn": "书名"}],
books: []
}
},
mounted() {
axios
.get('http://localhost:8080/book/books')
.then(response => (
this.books = response.data
))
.catch(function (error) { // 请求失败处理
console.log(error);
});
}
}).use(ElementPlus).mount('#app')
</script>
</body>
</html>
测试结果: 运行spring boot
项目,打开浏览器,直接输入http://localhost:8080/index.html
。可看到如下图所示结果。
3.2 物理分离
物理分离是真正意义上的前后端分离模板,此分离模式除了服务器端项目,还有独立的基于VUE
框架的前端项目。项目中能使用VUE
单页面,能真正意义上实现组件化编程思想。
创建VUE
项目有很多种方式,也有很多优秀的前端开发工具,本文使用HBuild
以及其项目创建向导构建VUE
项目。
3.2.1 新建 VUE
项目
打开HBuild
,新建项目,且选择使用vite
构建项目。如下图所示:
新建的项目自动依赖了VUE和vite
模块。可以打开项目中的package.json
查看相关信息。
为了能使用axios和 Element Plus
,需要在项目中安装这两个模块库。
右击项目,在弹出来的快捷菜单中选择使用命名行窗口打开所在目录
。在HBuild
下面可看到终端
窗口。
安装axios
模块,在命令模式下输入:
Tips:
axios
的使用请查阅官方文档。
npm install axios
安装element-plus
模块,在命令模式下输入:
npm install element-plus --save
可以在package.json
文件中查看模块的依赖信息。
为了使用element plus
的自动导入功能,还需要安装unplugin-vue-components 和 unplugin-auto-import
插件。在命令模式下输入如下指令进行安装。
npm install -D unplugin-vue-components unplugin-auto-import
打开vite.config.js
文件,添加如下的配置信息:
为了实现axios
的跨域访问。还需要后端项目中新建配置类,且添加如下内容。
@Configuration
public class CorsConfig {
@Bean
CorsFilter corsFilter() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(Collections.singletonList("*"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}
}
如下图所示:
3.2.2 创建前端页面
在VUE
项目中,页面可以是重用的组件。本文直接在已经创建的HelloWorld.vue
文件中进行修改,同样实现读取所有书籍。内容如下:
<script setup>
import {
ref,
reactive
} from 'vue'
import axios from 'axios'
defineProps({
msg: String
})
const data = reactive({
books: null
})
/*
* 使用 axios 请求服务器数据
*/
const getData = function() {
axios({
url: 'http://localhost:8080/book/books',
method: 'get',
headers: {
"Access-Control-Allow-Origin": "*",
}
}).then((res) => {
data.books = res.data
console.log(data.books)
});
}
</script>
<template>
<h1>{{ msg }}</h1>
<el-table :data="data.books" style="width: 100%">
<el-table-column prop="bookId" label="编号" width="180" />
<el-table-column prop="bookTitle" label="书名" width="180" />
<el-table-column prop="bookAuthor" label="作者" />
</el-table>
<el-button type="primary" @click="getData">查阅书籍</el-button>
</template>
<style scoped>
a {
color: #42b983;
}
</style>
启动前端、后端项目:
npm run dev
打开浏览器,在地址栏中输入:http://localhost:3000
。
点击查阅书籍:
4. 总结
本文通过一个案例,简要介绍了使用spring boot
和vue3
如何实现项目的前后端分离。