vue+elementUI 後臺管理極簡模板
寫在前面
此篇文章爲一篇說明文檔,不是教你從零構建一個後臺管理系統,而是基於一個實際項目,已經搭建好了一個後臺管理系統的基礎框架,教你如何在此基礎上快速開發自己的後臺管理系統,能讓讀者能在掌握一些基礎知識的情況下,也能上手vue後臺開發。只有接觸項目,才能更好地理解自己所學知識的意義,觸類旁通把死知識點變成活學活用的技能。
先跑起來
# 克隆項目
git clone https://github.com/tuture-dev/vue-admin-template.git
# 進入目錄
cd vue-admin-template
# 安裝依賴
npm install --registry=https://registry.npm.taobao.org
# 運行
npm run dev
增添側邊導航
- 新建文件。在src/views/ 新建一個空白的文件夾 test,在此目錄下新建文件 test.vue
- 添加路由。打開 src/router/index.js,此文件爲該項目的後臺路由配置文件。在constantRoutes這個數組中,添加路由的格式如下:
{
path: '/test', //url路徑
component: Layout, // 此處不用動,這個全局統一的一個佈局文件
children: [{
path: 'test', // 二級路徑
name: 'test',
component: () => import('@/views/test/test'), // 懶加載,此處寫所添加文件的路徑
meta: {
title: '測試', icon:'plane' //配置選項可配置測試名稱和圖標
}
}]
},
我們可以自定義圖標,格式的文件,可以在iconfont中下載,之後放入src/icons/svg 目錄下即可
對於二級導航可以按照如下的方式進行配置。
{
path: '/material',
component: Layout,
redirect: '/material/upload',
meta: {
title: '素材管理', //元信息,一級導航的名稱
icon: 'plane' // 元信息,導航圖標的名稱
},
children: [{
path: 'check-template',
name: 'check-template',
component: () => import('@/views/material/check-template'),
meta: {
title: '查看模板',
}
},
{
path: 'logo',
name: 'logo',
component: () => import('@/views/material/check-logo'),
meta: {
title: '查看logo',
}
},
{
path: 'generate',
name: 'generate',
component: () => import('@/views/material/generate'),
meta: {
title: '生成素材',
}
},
{
path: 'check',
name: 'check',
component: () => import('@/views/material/check'),
meta: {
title: '查看素材',
}
},
]
},
在此配置完成後,框架會自動地根據路由配置文件,生成邊側導航條目。我們所需要做的工作就是根據業務需求,編寫一個個vue組件,往框架裏面填充內容就OK了。
使用Element UI組件
Element UI提供了很多可複用的組件,對於一般的後臺應用,這些組件完全可以滿足需求。如果個性化需求不高的話,我們完全可以做一名“複製粘貼”工程師又稱“CV”工程師,快速開發。
對於每一個組件,其文檔上都有效果示例與代碼,只需選擇所需組件,將其代碼粘貼進我們的代碼文件中,稍加修改即可。
網絡請求
當整個框架搭建完畢以後,前端程序員最主要的工作就是發起請求,渲染數據。現在我們就來完整地走一遍這個過程。
基礎配置
- 配置代理。
因爲跨域資源請求的問題,在開發階段所有和後端交互的網絡請求在底層由node.js代理。相關文檔
打開根目錄下的vue.config.js文件
// 代理所有以‘/admin’開頭的網絡請求
proxy: {
'/admin': {
target: `http://localhost:8886/`, //後臺服務地址
changeOrigin: true,
pathRewrite: {
}
}
}
- 配置地址
生產環境與開發環境通常有不同的服務地址。編輯 .env.development 以及 .env.production 這兩個文件,修改其中的 VUE_APP_BASE_API 配置項即可
以開發環境爲例:
VUE_APP_BASE_API = '/admin'
- 配置攔截器
打開src/utils/request.js,此文件封裝了一個axios請求對象,該系統中的網絡請求都是基於這個對象來處理的。
我們可以在網絡請求發送之前和收到服務端回覆之後做一些通用性的工作。比如根據服務端的狀態碼判斷請求是否正常,若不正常給出相應的提示。
service.interceptors.response.use(
response => {
const res = response.data
// 如果服務器的狀態碼不爲200,說明請求異常,應給出錯誤提示。
if (res.code !== 200) {
Message({
message: res.msg || 'Error check your token or method',
type: 'error',
duration: 2 * 1000
})
return Promise.reject(new Error(res.msg || 'Error'))
} else {
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 2 * 1000
})
return Promise.reject(error)
}
)
- 掛載請求對象
在src/main.js首先導入網絡請求對象,並掛載至Vue全局對象,這樣在每個組件中直接引用即可,不用要再導入。
import request from '@/utils/request'
Vue.prototype.req = request
請求與渲染
- 搭建一個簡易node服務
僅供教程說明使用
let http = require('http');
let querystring = require('querystring');
let my_result = [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀區金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀區金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀區金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀區金沙江路 1516 弄'
}]
let server = http.createServer((req, res) => {
let post = '';
req.on('data', function (chunk) {
post += chunk;
});
req.on('end', function () {
res.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8'
})
post = querystring.parse(post);
console.log('post-data:', post);
if (post) {
let result = {
code: 200,
// msg: "server error"
data: my_result
}
res.end(JSON.stringify(result));
} else {
let result = {
code: '0',
msg: '沒有接受到數據'
}
res.end(JSON.stringify(result));
}
});
});
server.listen(8886)
//在命令行 node server.js 即可運行
- 發起請求
this.req({
url: "getInfo?id=6", // 此處寫不同業務對應的url,框架會自動與baseURL拼接
data: {},
method: "GET"
}).then(
res => {
// 請求成功後的處理
console.log("res :", res);
},
err => {
// 請求失敗後的處理
console.log("err :", err);
}
);
按照最佳實踐,應該把網絡請求統一抽離到單一文件,然後在每個具體的頁面進行對服務端數據的處理。
比如下面的這種形式,首先創建文件src/api/test.js,把在test組件中需要用到的網絡請求都寫入此文件。
// src/api/test.js
import request from '@/utils/request'
export function getList(params) {
return request({
url: 'getTableData',
method: 'get',
params
})
}
在組件test.vue中引入請求方法
import { getTableData } from "@/api/test.js";
……
mounted: function() {
// 網絡請求統一處理
getTableData().then(res => {
console.log("api tableData :", res);
this.tableData = res.data;
},err=>{
console.log("err :", err);
});
// 網絡請求直接寫在文件中
this.req({
url: "getTableData",
data: {},
method: "GET"
}).then(
res => {
console.log("tableData :", res);
this.tableData = res.data;
},
err => {
console.log("err :", err);
}
);
},
- 網絡數據流
在控制檯可以看出,我們的請求地址爲localhost:9528,而後臺服務的的地址爲localhost:8886。爲啥不一樣呢?我們以一流程圖說明
應用程序上線後,對於CORS跨域資源訪問的問題,可以用類似的方案(Nginx反向代理)在前端解決。
Hello Table
現在我們在test.vue中用Element UI所提供的 Table組件寫一個表格數據展示頁面。
- 進入Element UI Table組件的說明文檔,複製粘貼對應的代碼。框架對於Element UI已經進行了全局引入,所以這些組件拿來即用。如果是其他第三方的組件,還需要我們自己引入後再使用。
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
</template>
- 在組件裝載時請求數據
mounted: function() {
this.req({
url: "getTableData",
data: {},
method: "GET"
}).then(
res => {
console.log("tableData :", res);
this.tableData = res.data // 數據渲染
},
err => {
console.log("err :", err); // 當業務邏輯發生錯誤時 進行處理
}
);
},
- 實際效果
業務邏輯正常
業務出錯時,彈出服務端給的錯誤信息。彈出此信息是在攔截器request.js文件定義的,這是統一的業務邏輯錯誤處理,也可以在每個請求中單獨處理。
簡易權限控制
這種權限控制方式爲靜態方式,有些複雜的動態權限管理不在此說明。
該框架每一次的路由跳轉都會通過router.beforeEach檢驗一遍權限,我們可以在這裏添加配置項。
進入文件 src/permission.js,以只有管理員才能進入用戶管理界面爲例:
if (to.path === '/user/user') {
let id = JSON.parse(localStorage.getItem('userInfo')).id
console.log(id)
if (id > 2) { //id>2位普通用戶,無權訪問
next({ path: '/task' })
window.alert('permission denied')
}
}
結語
到此後臺開發中最常用的操作已經介紹完畢,對於一些小項目已經是綽綽有餘。花盆裏長不出參天松,庭院裏練不出千里馬,項目寫得多了很多東西就自然而然的通透了。一千個讀者就有一千個哈姆雷特,這只是一個基礎框架,在開發的過程,需要我們自己對其修改,讓它成爲你自己最順手的框架。
此項目演繹自: https://github.com/PanJiaChen/vue-admin-template.git