本篇文章我們來實作一個簡單的前后端分離功能——學生系統,前端采用Vue+ElementUI,后端采用SpringBoot+MyBatis,
文章里不會介紹相應的技術內容,而是闡述整個前后端開發的流程
環境準備
在正式開始開發之前,我們先來準備一下開發環境,為了避免一些錯誤的發生,請保持與我的環境版本一致,
首先下載node.js,來到官網:https://nodejs.org/zh-cn/download/releases/

下載14.15.0的安裝包,下載完成后一路next即可安裝成功,安裝成功后驗證一下,打開cmd視窗,執行命令:
node -v
若是輸出了版本號則表示安裝成功,接著配置一下淘寶鏡像,它可以加速依賴的下載:
npm config set registry https://registry.npm.taobao.org
本次專案我們使用vue-element-admin腳手架作為基礎框架進行開發,所以需要下載它,來到GitHub:
https://github.com/PanJiaChen/vue-admin-template

將專案下載或者克隆下來,下載完成后解壓就可以得到一個現成的后臺管理系統,打開cmd視窗,將路徑切換到該專案下,執行指令:
npm i
npm就會幫助我們下載專案需要用到的依賴,等待其下載完成:

出現警告是正常的,沒有出錯就行,現在我們就可以啟動這個專案了,執行指令:
npm run dev

直接點擊登錄按鈕就可以進入后臺了:

目前這個后臺還是個空殼子,接下來的任務就是來實作它,
腳手架專案介紹
如果你是初次接觸Vue的腳手架專案,在看到專案中如此多的檔案時,一定會手足無措吧,沒關系,我們就先來分析一下專案結構,
對于Vue的腳手架專案,它有一個入口檔案main.js:
import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/en' // lang i18n
import '@/styles/index.scss' // global css
import App from './App'
import store from './store'
import router from './router'
import '@/icons' // icon
import '@/permission' // permission control
if (process.env.NODE_ENV === 'production') {
const { mockXHR } = require('../mock')
mockXHR()
}
Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式宣告
// Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
該檔案內容非常簡單,前面的11行都是引入一些模塊和組件,我們無需關心,重點看23~27行,這5行中,創建了一個Vue的實體,并將其系結到了id為app的DOM元素上,并使用render屬性進行渲染,所以它的作用就是將App組件的內容渲染到id為app的DOM元素上,那么找找id為app的DOM元素在哪呢?
在public目錄下的index.html中即可找到它的身影:

代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
有必要解釋一下,Vue的腳手架一般都是SPA(Single Page Application)專案,即:單頁面應用程式,
所以整個專案中只有這么一個頁面,而頁面的變化就是由這個id為app的div實作的;在main.js中,它將App組件渲染到了這個div中,所以頁面的內容實際上是由App組件決定的,
在專案的根目錄下即可找到App組件:

代碼如下:
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
一個Vue的組件由三部分組成,template、script和style,其中template用于展示頁面內容,這里只寫了一個標簽,route-view是路由標簽,它將根據路由規則來決定具體展示的內容是什么,所以查看一下路由的規則,
在router目錄下有一個index.js,它就是用來配置路由規則的:

這個檔案里的內容非常多,這里截取部分進行分析:
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: 'Dashboard', icon: 'dashboard' }
}]
}
]
path用于指定路由規則,component指定組件,Vue會監聽地址欄的地址變化,當地址欄變為/login時,Vue便會使用component中配置的組件替換掉剛才的路由標簽route-view,
學生資訊-前端開發
剛才簡單地介紹了一下Vue的腳手架專案,接下來我們就來實作一個學生資訊的管理,首先添加路由規則:
{
path: '/student',
component: Layout,
children: [
{
path: 'index',
name: 'Student',
component: () => import('@/views/student/index'),
meta: {title: '學生資訊', icon: 'form'}
}
]
},
將其放到router目錄下index.js中的constantRoutes屬性里即可:

這里再說說這行代碼吧:
component: () => import('@/views/student/index')
它的作用是引入一個組件用于顯示當前路由匹配的內容,@表示src目錄,所以我們需要在src/views目錄下新建一個student目錄,并在student目錄下新建index.vue檔案:

index.vue內容如下:
<template>
<div>
學生資訊
</div>
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped>
</style>
看看效果如何:

這樣一個選單項就定義出來了,接下來就是對右側頁面的撰寫了,右側我們使用一個表格來實作學生的資訊展示,來到Element-UI的官網:https://element.eleme.cn/#/zh-CN/component/installation
找到表格內容:

將表格內容的代碼復制粘貼到student目錄下的index.vue中即可:
<template>
<div>
<el-table
:data="tableData"
stripe
style="width: 100%">
<el-table-column
prop="id"
label="學號">
</el-table-column>
<el-table-column
prop="name"
label="學生姓名">
</el-table-column>
<el-table-column
prop="project"
label="專業">
</el-table-column>
<el-table-column
prop="class"
label="班級">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
看看頁面效果:

表格有了,接下來就是準備資料了,
學生資訊-后端開發
在資料庫中創建一張學生資訊表:
create database class_system;
use class_system;
create table student(
id varchar(10) primary key not null,
name varchar(50) not null,
project varchar(50) not null,
class varchar(50) not null
);
這里的班級應該創建一張班級表并建立外鍵關聯,這里為了方便開發,就設定成了字符型別,添加幾條測驗資料:
insert into student value ('1809100001','張三','計算機科學與技術','18計算機1班');
insert into student value ('1809100002','李四','計算機科學與技術','18計算機1班');
insert into student value ('1809100003','王五','計算機科學與技術','18計算機2班');
創建一個SpringBoot應用,并引入相關的依賴:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
創建物體類:
@Data
public class Student {
private String id;
private String name;
private String project;
// 資料庫中班級的欄位名為class,在Java中class與關鍵字沖突,所以使用@TableField注解標注一下屬性和欄位名的對應關系
@TableField("class")
private String theClass;
}
撰寫Mapper介面:
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}
撰寫Service介面:
public interface StudentService{
List<Student> findAll();
}
撰寫Service介面的實作類:
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> findAll() {
return studentMapper.selectList(null);
}
}
最后在application.yml中配置一下資料庫的相關資訊:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql:///class_system
測驗一下方法是否有用:
@SpringBootTest
class ClasssystemApplicationTests {
@Autowired
private StudentService studentService;
@Test
void contextLoads() {
List<Student> students = studentService.findAll();
students.forEach(System.out::println);
}
}
運行結果:
Student(id=1809100001, name=張三, project=計算機科學與技術, theClass=18計算機1班)
Student(id=1809100002, name=李四, project=計算機科學與技術, theClass=18計算機1班)
Student(id=1809100003, name=王五, project=計算機科學與技術, theClass=18計算機2班)
為了方便前后端的聯系,這里簡單封裝一下回應結果:
@Data
public class R {
private Integer code;
private Map<String, Object> data = new HashMap<>();
private R() {
}
public static R ok() {
R r = new R();
r.setCode(200);
return r;
}
public static R error() {
R r = new R();
r.setCode(500);
return r;
}
public R data(String key, Object value) {
this.data.put(key, value);
return this;
}
}
接下來就可以撰寫Controller了:
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/getStudents")
public R getStudents(){
List<Student> students = studentService.findAll();
return R.ok().data("students",students);
}
}
啟動SpringBoot應用,檢查一下回傳結果是否正確,訪問 http://localhost:8080/getStudents :

到這里后端的開發也就完成了,
學生資訊-前后端整合
到目前為止,我們實作了前端的頁面顯示,后端的介面開發, 接下來就是將資料介面運用到前端專案中,
首先修改前端專案根目錄下的.env.development檔案:

將檔案中的VUE_APP_BASE_API的配置值修改為我們后端應用的地址:
# base api
VUE_APP_BASE_API = 'http://localhost:8080'
但這會導致前端專案的登錄功能無法正常作業:

這是因為前端專案是用Mock.js自己寫的一個服務端實作的登錄,而當我們修改了BASE_API后,請求的路徑就被篡改了,所以修改根目錄下mock目錄中的mock-server.js檔案:

修改第37行的內容:

還需要修改src下api下的user.js檔案:

在該檔案的三個函式中都添加如下內容:

完成后重啟前端專案,就可以登錄到后臺了,
最后修改src下utils下的request.js檔案:

修改第49行的內容:

這樣前端專案就能正確收到后端專案的回應了,
接下來正式開始撰寫代碼,首先撰寫資料介面,在src/api目錄下新建student.js檔案:
import request from '@/utils/request'
export default{
list(){
return request({
url:'/getStudents', // 介面地址
method:'get')
}
}
}
然后在student下的index.vue中呼叫它:
<template>
<div>
<el-table
:data="list"
stripe
style="width: 100%">
<el-table-column
prop="id"
label="學號">
</el-table-column>
<el-table-column
prop="name"
label="學生姓名">
</el-table-column>
<el-table-column
prop="project"
label="專業">
</el-table-column>
<el-table-column
prop="theClass"
label="班級">
</el-table-column>
</el-table>
</div>
</template>
<script>
import studentApi from '@/api/student.js' // 引入Api檔案
export default {
data(){
return{
list:[]
}
},
// 生命周期鉤子
created(){
this.fetchData()
console.log(this.list)
},
methods:{
fetchData(){
studentApi.list().then(response=>{
this.list = response.data.students
})
}
}
}
</script>
<style scoped>
</style>
此時查看頁面效果,發現了新的問題:
這是前后端分離專案中十分常見的跨域問題,這里我先用一種比較簡便的方式解決它,就是在后端專案的Controller上添加@CrossOrigin注解:
@RestController
@CrossOrigin
public class StudentController {
......
}
重啟后端專案,查看頁面效果:

到這里一個完整的前后端分離功能就完成了,不知道現在大家對前后端分離的開發流程是否熟悉了呢?
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/289915.html
標籤:其他
