剛剛, 我們運行了模板, 看到了界面, 那為什么我們沒有后端項目這個模板就能直接運行呢?
因為其內(nèi)部使用了mock.js虛擬了接口
那么首先, 我們要先了解一下剛剛下載的模板的模擬登錄過程.
一. 理解原模板的mock模擬數(shù)據(jù)登錄過程
1. 表單提交登錄請求
首先,我們看 src\pages\login\Login.vue, 看我們點擊登錄時發(fā)生了什么:
我們發(fā)現(xiàn)點擊登錄時,表單提交觸發(fā)onSubmit方法

我們來看一下 onSubmit方法:

可以看到,第7步中調(diào)用了login方法. 我們看一下這個方法從哪引入的?

發(fā)現(xiàn)是 @/services/user 這可以很好理解, 登錄是一個服務(wù), 在網(wǎng)站設(shè)計中,我們往往把頁面文件和服務(wù)文件(API文件) 一 一對應(yīng)
下面, 我們來看一看login函數(shù)
2. 服務(wù)login函數(shù)

可以看到login里面只是進(jìn)行了一個封裝好的request請求, 沒什么特別的
我們注意到請求中的一個參數(shù) LOGIN, 他在@/services/api里, 我們?nèi)タ匆幌?
3. services/api

可以看到, 此文件非常簡單, 目前只有LOGIN ROUTES兩個url .同時寫好了將來跨域要用的代碼, 將來取消注釋即可.
這里我們注意到BASE_URL是 process.env.VUE_APP_API_BASE_URL
我們?nèi)フ疫@個全局變量
在工程根目錄下找到 兩個文件.env和.env.development, 我們可以把他們簡單的理解為"生產(chǎn)環(huán)境"和"開發(fā)環(huán)境"

當(dāng)然, 根據(jù)配置, 我們現(xiàn)在是開發(fā)環(huán)境 ,所以我們的請求是:http://dev.iczer.com/login
4. MOCK模擬接口
事實上, 當(dāng)我們點擊登錄后, 系統(tǒng)并沒有真的去請求這個地址, 根本就沒有發(fā)送真的請求

而是被mock接管:
我們來看 src\mock\user\login.js

看到這里我們明白了:
mock返回數(shù)據(jù)給service
↓
service返回數(shù)據(jù)給前端
↓
前端收到數(shù)據(jù)后進(jìn)行后續(xù)處理
我們就知道了, 如果我們自己寫后端, 也應(yīng)該這么返回數(shù)據(jù)
5. 后續(xù)處理 .then(this.afterLogin)
我們看看前端獲取到數(shù)據(jù)后做了什么

我們注意到:第7步 獲取路由配置時, 又進(jìn)行了一個請求, 我們按照上面的方法分析就可以找到他的MOCK源.
這是vue-antd-admin的一個動態(tài)路由功能,需要配置, 這個日后再實驗
二. 使用KOA2編寫后端接口代替MOCK
完成了上面的分析后, 我們現(xiàn)在開始嘗試用一個后端程序代替mock
1.新建koa2工程
koa2 vue-antd-admin-back
然后初始化工程
npm i
然后運行工程
npm run dev
訪問 : http://127.0.0.1:3000/ 已經(jīng)可以了
2. 解決跨域問題
參考文章: http://www.itdecent.cn/p/6009513b931e
安裝koa2-cors
npm i koa2-cors --save
然后在app.js中:
const cors = require('koa2-cors');
app.use(
cors({
origin: function(ctx) { //設(shè)置允許來自指定域名請求
if (ctx.url === '/test') {
return '*'; // 允許來自所有域名請求
}
return '*'; //只允許http://localhost:8080這個域名的請求
},
maxAge: 5, //指定本次預(yù)檢請求的有效期,單位為秒。
credentials: true, //是否允許發(fā)送Cookie
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], //設(shè)置所允許的HTTP請求方法'
allowHeaders: ['Content-Type', 'Authorization', 'Accept'], //設(shè)置服務(wù)器支持的所有頭信息字段
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'] //設(shè)置獲取其他自定義字段
})
);
3. 前端項目配置環(huán)境
將 .env.development內(nèi)的base_url修改為: http://127.0.0.1:3000/

將 src\services\api.js內(nèi)的跨域代理打開, 把代理設(shè)置為http://localhost:3000, 同時,為了URL和文件的統(tǒng)一, 我把LOGIN的url改為了${BASE_URL}/user/login

現(xiàn)在,我們已經(jīng)能看到請求了

這里,我們看到兩個請求, 第一個是OPTIONS請求,用來探測服務(wù)器連接是否正常, 第二個才是真正的POST請求
在后端也可以收到了請求

接下來, 我們按照MOCK的格式進(jìn)行響應(yīng)就可以了
4. KOA2響應(yīng)登錄POST請求
我們看到, 前端post請求發(fā)送到 http://localhost:3000/user/login

所以, 我們應(yīng)該響應(yīng)此請求
具體操作:
- 我們新建
routes\user.js文件
在里面寫入post響應(yīng)
const router = require('koa-router')()
router.prefix('/user')
router.post('/login', function (ctx, next) {
ctx.body = '這里寫響應(yīng),一會兒再寫'
})
module.exports = router
- 在app.js中引入這個route
const user = require('./routes/user')
app.use(user.routes(), user.allowedMethods())
- 下面,我們來具體寫這個響應(yīng), 參考mock寫就可以
具體參考第一節(jié)第4點
const router = require('koa-router')()
router.prefix('/user')
router.post('/login', function (ctx, next) {
let result = {}
const name = ctx.request.body.name
const password = ctx.request.body.password
console.log(ctx.request.body);
console.log(name);
console.log(typeof (name));
console.log(password);
console.log(typeof (password));
if (name !== 'admin' || password !== '888888') {
result.code = -1
result.message = '賬戶名或密碼錯誤(admin/888888)'
} else {
result.code = 0
console.log(typeof (result.code));
result.message = '上午好' + ',歡迎回來'
console.log(typeof (result.message));
result.data = {}
result.data.user = {
name: '熊爸',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/WhxKECPNujWoWEFNdnJE.png',
address: '泰安市',
position: {
CN: "社畜",
HK: "計算服務(wù)事業(yè)群",
US: "engineer"
}
}
console.log(typeof (result.data.user));
result.data.token = 'Authorization:' + Math.random()
console.log(typeof (result.data.token));
result.data.expireAt = new Date(new Date().getTime() + 30 * 60 * 1000)
console.log(typeof (result.data.expireAt));
result.data.permissions = [{ id: 'queryForm', operation: ['add', 'edit'] }]
console.log(typeof (result.data.permissions));
result.data.roles = [{ id: 'admin', operation: ['add', 'edit', 'delete'] }]
console.log(typeof (result.data.roles));
}
ctx.body = result
})
module.exports = router
現(xiàn)在,我們點擊登錄, 不出意外的失敗了??, 不用著急, 看一下請求

我們發(fā)現(xiàn)
我們的login的POST請求已經(jīng)成功,而且得到了返回數(shù)據(jù)

但是根據(jù)之前的分析, login后會觸發(fā)afterlogin, 發(fā)送一個http://localhost:3000/routes請求(參考第一節(jié)第5點), 但我們還沒有處理這個get請求

5. 處理后續(xù) http://localhost:3000/routes 的get請求
這個請求其實是用戶登錄后申請動態(tài)路由資源的請求, 但是, 前端項目默認(rèn)并沒有開啟動態(tài)路由, 所以我們可以非常簡單的就把它處理好(其實只需要返回一個返回碼0)
新建routes\routes.js
const router = require('koa-router')()
router.prefix('/routes')
router.get('/', function (ctx, next) {
let result = {}
result.code = 0
data = {}
})
module.exports = router
在app.js中
const routes = require('./routes/routes')
app.use(routes.routes(), routes.allowedMethods())
再點擊登錄,就可以成功了

現(xiàn)在, 我們已經(jīng)完成登錄并跳轉(zhuǎn)到 /dashboard/workplace

由于我使用的是極簡模板, 所以跳轉(zhuǎn)錯了, 我們只需要src\pages\login\Login.vue的afterLogin()方法的路由跳轉(zhuǎn)改掉就可以了

三. 動態(tài)路由
上面, 雖然我們完成了登錄進(jìn)程, 但我們并沒有實現(xiàn)動態(tài)路由, 如果我們想實現(xiàn)動態(tài)路由可以參考以下文章:
https://iczer.gitee.io/vue-antd-admin-docs/advance/async.html
具體步驟:
1. 在 /config/config.js 文件中設(shè)置 asyncRoutes 的值為 true

2. 注冊路由組件
我們要把 視圖和路由 配置起來,來確保頁面有辦法被訪問到, 確保路由能夠獲取到頁面
所有這一切在/router/async/router.map.js中實現(xiàn)
路由按照如下的格式來注冊:
registerName: { //路由組件注冊名稱,唯一標(biāo)識
path: 'path', //路由path,可缺省,默認(rèn)取路由注冊名稱 registerName 的值
name: '演示頁', //路由名稱
redirect: '/login', //路由重定向
component: () => import('@/pages/demo'), //路由視圖
icon: 'permission', //路由的菜單icon,會注入到路由元數(shù)據(jù)meta中
invisible: false, //是否隱藏菜單項,true 隱藏,false 不隱藏,會注入到路由元數(shù)據(jù)meta中。
authority: { //路由權(quán)限配置,會注入到路由元數(shù)據(jù)meta中。可缺省,默認(rèn)為 ‘*’, 即無權(quán)限限制
permission: 'form', //路由需要的權(quán)限
role: 'admin' //路由需要的角色。當(dāng)permission未設(shè)置,通過 role 檢查權(quán)限
},
page: { //路由的頁面數(shù)據(jù),會注入到路由元數(shù)據(jù)meta中
title: '演示頁', //頁面標(biāo)題
breadcrumb: ['首頁', '演示頁'] //頁面面包屑
}
}


3. 配置基本路由
如果沒有任何路由,你的應(yīng)用是無法訪問的,所以我們需要在本地配置一些基本的路由,比如登錄頁、404、403 等。你可以在 /router/async/config.async.js 文件中配置一些本地必要的路由。
這個基本不用動
4. 后端返回動態(tài)路由
我們要按照文檔要求的格式返回路由請求 routes\routes.js
const router = require('koa-router')()
router.prefix('/routes')
router.get('/', function (ctx, next) {
let result = {}
result.code = 0
result.data = [
{
router: 'root',
children: [
{
router: 'demo',
path: 'demo',
name: '演示頁',
icon: 'file-word',
authority: {role: 'admin'}
},
{
router: 'parent1',
children: ['exp404','exp403','exp500'],
},
]
}
]
ctx.body = result
})
module.exports = router