項目總結:中后台管理系統類


項目類一:中后台管理系統類

中后台系統類多為內部人員使用。采用Vue+elementUI開發。

技術選型的理由有以下幾點:

  1. 此類項目多為表單、列表、數據看板,vue生態有成熟的解決方案。
  2. 產品設計風格與elementUI設計風格相近。
  3. 團隊成員更擅長使用Vue開發后台管理類項目,可以快速開發,節省成本。

一般的中后台管理系統實現的功能有以下幾類:

  1. 模塊化開發:功能、組件、路由、vuex的實現。
  2. 權限控制:請求權限,動態路由,按鈕權限的實現。
  3. 數據看板:Echart的使用。
  4. 項目mock:后端未提供API時,模擬數據。
  5. 多環境配置:dev(開發)、sit(測試)、stage(預發)prod(生產)
  6. 國際化:i18n的配置。

模塊化開發

模塊化開發可以解決命名沖突、文件依賴的問題,方便多人協作開發,提升開發效率,方便后期維護。

  1. 公共組件抽離出來可以復用。
  2. 頁面、路由、vuex(namescaped)根據模塊划分。

權限控制

請求權限的實現

  1. 登錄拿到token,存入cookie
  2. 每一個請求,都會在請求header里面攜帶用戶的token
  3. 后端會根據該token來驗證用戶是否有權限執行該操作

動態路由的實現

  1. 創建vue實例的時候掛載vue-router,登錄頁和不用權限的頁面
  2. 通過token獲取用戶的role和有權限的api列表perms['GET /aaa','POST /bbb',...]
  3. 算出其相應有權限的路由,通過router.addRoutes動態掛載路由
  4. 使用vuex管理路由表,根據vuex中可訪問的路由渲染側邊欄組件
// 用戶登錄拿到的perms為['GET /admin/goods/list', ...] let userInfo = { role: 'operator', perms: ['GET /admin/goods/list'] } // 路由中的權限在meta中的perms中設置,該頁面用到的的api let childRoute = { path: 'list', component: () => import('@/views/goods/list'), name: 'goodsList', meta: { perms: ['GET /admin/goods/list', 'POST /admin/goods/delete'], title: '商品列表', noCache: true } } // 在 vuex 中進行管理,算出其相應有權限的路由 const permission = { state: { routers: constantRouterMap, addRouters: [] }, mutations: { SET_ROUTERS: (state, routers) => { state.addRouters = routers state.routers = constantRouterMap.concat(routers) } }, actions: { GenerateRoutes({ commit }, data) { return new Promise(resolve => { const { perms } = data let accessedRouters if (perms.includes('*')) { accessedRouters = asyncRouterMap } else { accessedRouters = filterAsyncRouter(asyncRouterMap, perms) } commit('SET_ROUTERS', accessedRouters) resolve() }) } } } // 在router.beforeEach中判斷在第一次拉取權限時使用addRoutes添加可訪問路由表 router.beforeEach((to, from, next) => { // 判斷當前用戶是否已拉取完user_info信息 if (getToken() && store.getters.perms.length === 0) { // 拉取user_info store.dispatch('GetUserInfo').then(res => { // note: perms must be a array! such as: ['GET /aaa','POST /bbb'] const perms = res.data.data.perms // 根據perms權限生成可訪問的路由表 store.dispatch('GenerateRoutes', { perms }).then(() => { // 動態添加可訪問路由表 router.addRoutes(store.getters.addRouters) // hack方法 確保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record next({ ...to, replace: true }) }) }) } }) 

按鈕權限的實現

  1. 通過比較該按鈕請求的api是否在該用戶的有權限的api列表perms中
  2. 注冊permission指令,如果權限不符合,就移除該節點
<el-button v-permission="['POST /admin/goods/delete']" type="danger" @click="handleDelete">刪除</el-button> 
const permission = { inserted(el, binding, vnode) { const { value } = binding const perms = store.getters && store.getters.perms if (value && value instanceof Array && value.length > 0) { const permissions = value var hasPermission = false if (perms.indexOf('*') >= 0) { hasPermission = true } else { hasPermission = perms.some(perm => { return permissions.includes(perm) }) } if (!hasPermission) { el.parentNode && el.parentNode.removeChild(el) } } else { throw new Error(`need perms! Like v-permission="['GET /aaa','POST /bbb']"`) } } } const install = function(Vue) { Vue.directive('permission', permission) } if (window.Vue) { window['permission'] = permission Vue.use(install) } permission.install = install export default permission 

Echart的使用

  1. 按需引入ECharts
// 引入 ECharts 主模塊 var echarts = require('echarts/lib/echarts'); // 引入柱狀圖 require('echarts/lib/chart/bar'); // 引入提示框和標題組件 require('echarts/lib/component/tooltip'); require('echarts/lib/component/title'); 
  1. 在vue中的mounted生命周期里聲明初始化ECharts。(ECharts初始化必須綁定dom。)
mounted() {
  this.initCharts(); }, methods: { initCharts() { this.chart = echarts.init(this.$el); this.setOptions(); }, setOptions() { this.chart.setOption({ title: { text: 'ECharts 入門示例' }, tooltip: {}, xAxis: { data: ["襯衫", "羊毛衫", "雪紡衫", "褲子", "高跟鞋", "襪子"] }, yAxis: {}, series: [{ name: '銷量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] }) } } 
  1. 數據變化時,通過watch觸發setOptions

項目mock

項目mock 模擬產生一些虛擬的數據,可以讓前端在后端接口還沒有開發出來時獨立開發,加快開發速度。

  1. 使用 promise 和 setTimeout 模擬數據
  2. 使用 mockjs,mockjs可以攔截ajax請求,返回設定好的數據。
  3. 使用例如easy-mock/doc Docker等

多環境配置:dev(開發)、sit(測試)、stage(預發)prod(生產)

{
  "scripts": { "dev": "cross-env BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "build:stage": "cross-env NODE_ENV=production env_config=stage node build/build.js", "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js", "lint": "eslint --ext .js,.vue src", "test": "npm run lint", "precommit": "lint-staged" }, } 

在config文件夾下的prod.env.js配置如下

module.exports = { NODE_ENV: '"production"', ENV_CONFIG: '"prod"', BASE_API: '"http://xxx/admin"' } 

在代碼中即可用process.env.env_config使用判斷啦

國際化:i18n的配置。

  1. 安裝npm install vue-i18n -D
  2. 在src下新建文件i18n.js
import Vue from 'vue' import VueI18n from 'vue-i18n' Vue.use(VueI18n) export const i18n = new VueI18n({ locale: 'CN', messages: { 'CN': require('./assets/lang/cn'), 'EN': require('./assets/lang/en') } }) 
  1. 在assets/lang下新建文件en.js和cn.js
// en.js export const message = { hello: 'Hello, World' } // cn.js export const message = { hello: '你好, 世界' } 
  1. 在main.js里引入i18n.js
import { i18n } from './i18n' new Vue({ el: '#app', i18n, ... }) 
  1. 使用<span>{{ $t("message.hello") }}</span>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM