前端后台管理系统梳理
再梳理一遍
一、商品后臺管理系統
1. 功能
1.1 服務端情況
- 開啟了CORS跨域支持
- 需要授權的 API ,必須在請求頭中使用 Authorization 字段提供token 令牌(axios攔截器)
- baseUrl,接口地址:http://localhost:8888/api/private/v1/
token令牌在服務端生成,當登錄成功時,post請求返回的用戶信息里包含了這一元素:
1.1.1 axios發ajax請求
Axios:通過promise實現對ajax技術的一種封裝,ajax只能訪問同源的請求。axios并沒有install 方法,所以是不能使用vue.use()方法的。為了不在每個文件都引用一次axios,將它改造成vue插件。
1)使用
axios.get('/user?ID=12345').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});2) 改造為vue插件
plugins/http.js
main.js里安裝插件
import http from '@/plugins/http.js' Vue.use(http)1.1.2 攔截器 – 向服務端發請求需要token
httpAxios.install = function (Vue) {const instance = axios.create({baseURL: 'http://127.0.0.1:8888/api/private/v1'}) ?instance.interceptors.request.use(function (config) {if (config.url.toLowerCase() !== 'login') {const token = sessionStorage.getItem('token')config.headers.Authorization = token}return config}, function (error) {return Promise.reject(error)})Vue.prototype.$http = instance }1.1.3 路由導航守衛 – 權限控制
路由的前置守衛 router.js
router.beforeEach((to, from, next) => {console.log(to, from)if (to.name === 'login') {next()} else {const token = sessionStorage.getItem('token')if (!token) {router.push({ 'name': 'login' })Message.warning('請先登錄')return}next()} })1.1.4 使用async和await
handleLogin () {this.$http.post('login', this.formData).then((res) => {const data = res.dataconst {meta: {status, msg}} = dataif (status === 200) {const token = data.data.tokensessionStorage.setItem('token', token)this.$message.success(msg)} else {this.$message.error(msg)}}) } async handleLogin () {const res = await this.$http.post('login', this.formData)const data = res.dataconst { meta: { status, msg } } = dataif (status === 200) {const token = data.data.tokensessionStorage.setItem('token', token)this.$message.success(msg)} else {this.$message.error(msg)} }外層方法使用async關鍵字(await最近的外層函數要加上async),發請求代碼前加 await,省略.then
1.2 自定義組件
以自定義面包屑組件(子組件)為例,父組件(使用到面包屑的組件)向子組件傳值。
子組件:
父組件:
<my-bread level1='權限管理' level2='角色列表'></my-bread>1.3 登錄
- 組件el-form 表單
- :rules=“rules” 表單驗證,show-password
- 登錄按鈕的點擊事件:
1)表單驗證是否通過
2)通過設置token,跳轉到主頁 - 頭像:css設置水平居中
- 全局監聽enter鍵(把監聽事件綁定到document上),當(that.$route.path === ‘/login’) && (e.keyCode === 13),觸發登錄方法
1.4 主頁
- 布局
- 頭部+左側導航菜單+主體
1.4.1 頭部,退出
- 刪除token sessionStorage.clear()
- 跳轉到登錄頁 this.$router.push({name: 'login'})
1.4.2 左側菜單 – 權限控制
- el-aside -> el-menu
- :router 開啟路由模式,設置el-menu-item的index值 為路由標識
- 動態渲染:不同身份登錄,權限控制
一級菜單和子菜單之間是并列關系,在知道有幾級菜單的情況下,思考:如果不知道有幾級菜單?
<el-menu :unique-opened=true :router=true><el-submenu :index="item1.order.toString()" v-for="(item1,i) in menus" :key="item1.id"><template slot="title"><i :class="iconlist[i]"></i><span>{{item1.authName}}</span></template><el-menu-item :index="item2.path" v-for="item2 in item1.children" :key="item2.id"><i class="el-icon-menu"></i><span>{{item2.authName}}</span></el-menu-item></el-submenu> </el-menu>1.5 系統功能
1.5.1 用戶管理 - 用戶列表 - 增刪改查
- 展示:現有用戶數量 GET
- 增加:用戶名、密碼、郵箱、手機,新增后重新加載頁面 POST
- 刪除:刪除后重新加載頁面 PUT
- 修改:DELETE
1)改基本信息:手機、郵箱
2)改角色:關系到權限 - 組件
面包屑、搜索框、表格、分頁組件、switch狀態轉換
1.5.1.1 顯示、搜索的處理
顯示:
在created的時候,調用this.getUserList(),拿到res的數據,賦值給data里的userlist
搜索:
<el-input @clear="getUserList" v-model="query" clearable @keyup.enter.native="getUserList">鍵盤抬起時/輸入框清空時,依然是觸發getUserList,該方法內部通過雙向數據綁定的query進行傳參查詢,接口文檔中,query參數可以為空,為空時顯示全量信息。
1.5.1.2 slot-scope=“scope” 參數傳遞
<el-table-column label="用戶狀態"><template slot-scope="scope"><!-- scope.row就是當前綁定的數據對象 --><el-switch @change="handleSwitchChange(scope.row)" v-model="scope.row.mg_state" active-color="#13ce66"inactive-color="#ff4949"></el-switch></template> </el-table-column>1.5.1.3 添加完成,清空文本框
for (const key in this.formData) {this.formData[key] = '' }1.5.1.4 編輯用戶,顯示已有信息
編輯按鈕所在行,通過slot-scope="scope"將被編輯用戶信息傳給方法editUser,通過初始化form(顯示用戶信息的el-form所綁定的內容)展示
editUser(user) {this.dialogFormVisibleEdit = truethis.form = user } <el-dialog title="編輯用戶" :visible.sync="dialogFormVisibleEdit"><el-form :model="form"><el-form-item label="用戶名" ><el-input v-model="form.username" disabled></el-input></el-form-item></el-form> </el-dialog>1.5.1.5 下拉框-顯示當前用戶角色
1.5.2 權限管理 - 權限列表、角色列表
1.5.2.1 權限列表
一到三級權限的名詞展示,可以作為后臺的文檔數據,不必作為一項功能
1.5.2.2 角色列表
- 添加角色(簡單提交)
- 編輯、刪除(簡單slot-scope傳參、delete請求)
- 分配角色(tag)
- 權限展示(表格展開行)
【難點1】 三級權限展示,樹形結構,row、col的結構
請求角色列表的產物,因此數據包含在getRoleList的返回值里。
理解el-row和el-col的關系,兩者包含成為一維。
代碼怎么寫:
- 先縱向看,有幾個一級權限就應當v-for循環出幾行
- 再橫向看,每個el-row里,拿一個el-col現實出當級權限,另一個el-col再作為一個整體來看(再看成一行兩列)
【難點2】 分配權限,樹形結構el-tree 全選、半選(如何展示)
- 展開所有的權限(樹形結構自帶的屬性:default-expand-all)
- 顯示:先勾選上擁有的三級權限(三層forEach,獲得所有三級權限的集合,賦值給checklistArr)
:default-checked-keys="checklistArr" - 提交:需要獲取所有的一、二、三級權限的集合(全選+半選),傳參修改
顯示:
editRight(role) {// checklist權限的集合,是個樹形結構this.checklist = role.childrenthis.currentRoleId = role.idvar tmpArr = []this.checklist.forEach(item1 => {var item2 = item1.childrenitem2.forEach(item2 => {var item3 = item2.childrenitem3.forEach(item3 => {tmpArr.push(item3.id)})})})this.checklistArr = tmpArr }提交:
async confirmRole() {let arr1 = this.$refs.mytree.getCheckedKeys()let arr2 = this.$refs.mytree.getHalfCheckedKeys()let arr = [...arr1, ...arr2]const res = await this.$http.post(`roles/${this.currentRoleId}/rights`, { rids: arr.join(',') }) }1.5.3 商品管理 - 列表、分類參數、商品分類
1.5.3.1 商品分類
分類接口設計:
重要參數type,type=2(返回一層、二層分類),type=3(返回前三層分類)
1.【難點3】樹形組件element-tree-grid在表格中的運用(組件選擇、配置)
- 表格樣式:樹形結構 +【是否有效】【級別】【操作】字段;
- 組件選擇:由于第一列的el-table-column要展示為樹形結構,因此使用組件element-tree-grid,all props of el-table-column are supported;
- 在獲取到三級商品分類后,element-tree-grid只需要綁定好對應的屬性,即可顯示。
2.【難點4】級聯選擇器-添加分類(理解接口type參數)
- 由于最細添加的是三級分類(或者添加一級、二級分類),因此級聯選擇器只用展示一、二級的父類,請求分類接口,type=2
- value / v-model: 選中項綁定值,是一個數組
- 級聯選擇器的handleChange方法,能獲取到最接近一層的父類參數分類id,配置級別和分類名稱,組成一個obj作為參數發POST請求
1.5.3.2 【難點5】分類參數 – 只允許為三級分類設置參數
- 級聯選擇器 type=3 展示出三級分類
- 動態(涉及列表展開)、靜態參數
如何限定只讓第三級被選中:
handleChange () {if (this.selectedOptions.length !== 3) {this.$message.warning('商品只能添加到三級分類')this.selectedOptions.length = 0}}1.5.3.3 【難點6】什么時候渲染出參數,tabs標簽頁改造
在el-tab-pane里含了el-table–綁定dynamicAttrs el-button
在點擊了級聯選擇器器之后,渲染出動、靜態參數
1.5.3.4 【體現功能】商品列表 - 1000條數據
商品參數數據格式:
參數名–參數值(可能有多個)
- 查詢名稱、價格、重量、參數管理
- 添加商品詳細描述(名稱、價格、重點、數量、分類、參數、屬性、圖片)
- 步驟條組件+縱向tabs組件(需要包裹在el-form里)(并列關系)
- 上傳圖片(餓了么Upload組件、百度Web Uploader)
- 富文本編輯器
- 功能上的bug,商品列表不能顯示圖片(接口沒返回這個字段)
- bug2,數據庫表設計時,時間字段長度太短,導致時間不正確,令人汗顏
改了表字段的數據類型,可能不是最合適,但是時間顯示正常了。創建時間的時候,還是以1970位默認值。
1. 上傳圖片 – 拓展,檢測文件格式;性能
請求上傳接口,需要設置token(這里不是發axios請求)
<el-upload action="http://47.xxx.1xx.7:8888/api/private/v1/upload" :headers="header" :on-remove="handleRemove" :on-success="handleSuccess" :file-list="fileList" list-type="picture"><el-button size="small" type="primary">點擊上傳</el-button><div slot="tip" class="el-upload__tip">只能上傳jpg/png文件,且不超過500kb</div> </el-upload>header: {Authorization: sessionStorage.getItem('token') }2. 富文本編輯器組件 vue-quill-editor
<quill-editor v-model="form.goods_introduce"></quill-editor>1.5.4 訂單管理
1.5.5 數據統計
2. 框架選擇 – vue
3. 組件庫
3.1 elementUI
3.1.1 vue-cli安裝插件
vue create mypro cd mypro vue add element這里選擇的是按需引入:
觀察項目文件夾中多了plugins-element.js
默認按需引入只引入了{Button組件} (可以減小體積),修改代碼
3.1.2 echarts
4. 項目結構
一般腳手架都應當有以下的幾個功能:
- 自動化構建代碼,比如打包、壓縮、上傳等功能
- 本地開發與調試,并有熱替換與熱加載等功能
- 本地接口數據模擬
- css 模塊化:拓展語言、預處理器saas、less(css 不是編程語言,所以不能聲明變量、函數,不能做判斷、循環和計算,也不能嵌套)
- 檢查并自動矯正不符合規范的代碼,并優化代碼格式
定義好項目的目錄結構
- 解耦:代碼盡量去耦合,這樣代碼邏輯清晰,也容易擴展
- 分塊:按照功能對代碼進行分塊、分組,并能快捷的添加分塊、分組
- 編輯器友好:需要更新功能時,可以很快的定位到相關文件,并且這些文件應該是很靠近的,而不至于到處找文件
5. 亮點
- 權限、商品分類涉及到多層級的樹形結構
- 權限控制
總結
以上是生活随笔為你收集整理的前端后台管理系统梳理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 西工大计算机学院软件工程专硕,念念不忘,
- 下一篇: 街上第一台电子计算机是,南京信息工程大学