本文档从零开始搭建一个通用的管理后台,技术栈为vue2.0 + vue-router + vuex + element-ui + axios 。最终效果如下:

左侧为菜单栏,右侧包含头部,面包屑,主内容区。左侧菜单栏可折叠,可全屏,刷新页面后还是之前页面状态。gitee地址:

https://gitee.com/liubangbo/yilin-admain/tree/master

如对您有帮助,麻烦给个star。另外如有问题,欢迎在此留言讨论。

下面对此框架主要部分进行详细阐述。

1. 准备工作

此框架采用了vue-cli 脚手架创建的项目,选中vuex vue-router,然后按官方文档安装element-ui 并按需加载。最后在安装sass sass-loader的时候如果报错的话,则直接在package.json的devDependencies字段加上"sass": "^1.53.0",  "sass-loader": "^8.0.2",  再npm install 一下就可以了。

2. 模块化业务

业务按模块划分,在每个模块下写上路由,以及vuex状态。通过接口获取动态路由,对动态路由进行了一个map映射,这样前端就可以自己组织页面结构了。这一块代码在src/register-route-store.js 中:

import { router, store } from "./main";
// import { get } from "./http/index.js";  //real routes fetched from platform
import { get } from "./mockRoutes.js";  //mock routes export let routesMap = new Map();const recursionRoutes = (destRoutes, sourceRoutes) => {if (sourceRoutes.length) {let temp = null;sourceRoutes.forEach((item, index) => {temp = routesMap.get(item.id) ? routesMap.get(item.id) : {};destRoutes.children &&destRoutes.children.push(Object.assign({path: temp.path,component:`${item.children}` && `${item.children.length}`? (resolve) =>require(["@/layouts/components/rightRouteView/index.vue",], resolve): temp.component,children:`${item.children}` && `${item.children.length}` ? [] : null,},{meta: {label: item.label,icon: item.icon,},}));if (item.children && item.children.length) {recursionRoutes(destRoutes.children[index], item.children);}});}
};const register_dynamicRoutes_store = (dynamicRoutes) => {console.log("dynamic routes: ", dynamicRoutes);let routes = [...require("@/layouts/routes/index.js").default];store.registerModule("layouts", require("@/layouts/store/index.js").default);dynamicRoutes.length &&dynamicRoutes.forEach((item, index) => {require(`@/views${item.path}/routes/index.js`);routes[0].children.push(Object.assign({path: item.path,component: (resolve) =>require([`${item.children}` && `${item.children.length}`? "@/layouts/components/rightContent/index.vue": `@/views${item.path}`,], resolve),children:`${item.children}` && `${item.children.length}` ? [] : null,},{meta: {label: item.label,icon: item.icon,},}));store.registerModule(item.path.slice(1),require(`@/views${item.path}/store/index.js`).default);if (item.children && item.children.length) {recursionRoutes(routes[0].children[index], item.children);}});console.log("mapped routes is: ", routes);router.addRoutes(routes);store.commit("layouts/setSubRoutesList", routes[0].children);
};const register_login_route = () => {const routes = [...require("@/views/login/routes/index.js").default];router.addRoutes(routes);
};export const getRoutes = async () => {try {const res = await get({urlKey: "layouts-getNav",});if (res.success && res.data && res.data.length) {//had login, register dynamic routesregister_dynamicRoutes_store(res.data);router.replace({ path: "/" });}} catch (error) {//no login, register login routeconsole.error("get nav error, go to login: ", error);register_login_route();router.push({path: "/login",});}
};
getRoutes();

3. axios封装

之前接触的框架,网络接口一般定义在一个文件中,所有业务模块用到的网络接口都写到一个文件中,文件比较长,维护起来也费尽。这里我们把网络接口也进行了业务划分,每个模块写自己用到的网络接口。这部分代码在src/http/index.js文件中:

import axios from "axios";
import { getStorage } from "@/common/js/util.js";
import { TOKEN } from "@/common/js/constant.js";let pagesUrls = [];
pagesUrls.push({key: "layouts-getNav",url: "web/user/getNav",
});
const _pagesUrls = require.context("../views/", true, /urls\/index\.js/);_pagesUrls.keys().forEach((key) => {const _moduleName = key.split("/")[1];const _moduleUrls = require("@/views/" +_moduleName +"/urls/index.js").default;pagesUrls.push(..._moduleUrls);
});const urlMap = new Map();
pagesUrls.forEach((i) => {if (i.url) {urlMap.set(i.key, {url: "/" + i.url.replace(/^\//, ""), //  both sg/cms/homepage  and  /sg/cms/homepage  are OK});}
});let _httpRequest = (obj, _method) => {if (Object.prototype.toString.call(obj) !== "[object Object]") {console.error(`the params of http request should be Object`);return;}if (!obj.urlKey || !obj.urlKey.length) {console.error(`url is empty, you should set it`);return;}const hostKey = obj.hostKey || "HOST";let _url = urlMap.get(obj.urlKey).url;if (obj.dynamic) _url = `${_url}${obj.dynamic}`; //dynamic urldelete obj.urlKey;delete obj.hostKey;return new Promise((resolve, reject) => {let _params = {method: _method,url: _url,baseURL: process.env[`VUE_APP_${hostKey.toUpperCase()}`],};Object.assign(_params, obj);axios(_params).then((res) => {resolve(res.data);}).catch((err) => {console.error("axios error: ", err.response);if (err.response.data.code === 401) {// loginAgain()}reject(err);});});
};axios.interceptors.request.use((config) => {const token = getStorage(TOKEN);if (token) {config.headers["novaAuth"] = token;} else {config.headers["Authorization"] = "Basic dGVuYW50OjEyMzQ1Ng==";}return config;
});axios.interceptors.response.use((res) => {console.log("http res: ", res);//TODO token过期需要处理return res;
});
/*** get方法,对应get请求* @param {Object} obj*/
export function get(obj) {return _httpRequest(obj, "GET");
}
/*** post方法,对应post请求* @param {Object} obj*/
export function post(obj) {return _httpRequest(obj, "POST");
}

4. 常量定义

在项目中如果多人协作开发,定义通用常量还是比较重要的,防止出现奇怪bug。例如local-storage的key,我们统一写到常量文件中。这部分代码在src/common/js/constant.js中:

const TOKEN = "iotToken"
const USER_NAME = "userName"const TABS = "tabs"
const ACTIVE_TAB = "activeTabs"export {TOKEN,USER_NAME,TABS,ACTIVE_TAB
}

5. 假路由数据

在这个通用框架中我们定义了一个假路由数据,如果你们后端返回的动态路由和这个假路由一样,那么这个框架就可以直接拿来用了,直接上手写业务。假路由数据在src/mockRoutes.js中。

const mockRoutes = {code: 200,success: true,data: [{id: "8",icon: "el-icon-setting",label: "系统管理",path: "/config",children: [{id: "9",icon: "el-icon-setting",label: "页面管理",path: "/web",children: [],},],},{id: "100",icon: "el-icon-user",label: "测试",path: "/test",children: [{id: "101",icon: "el-icon-user",label: "测试一级菜单",path: "/test1",children: [{id: "101-0",icon: "el-icon-user",label: "一级子页面",path: "/big",children: [],},],},{id: "102",icon: "el-icon-user",label: "测试一级页面",path: "/test2",children: [],},{id: "103",icon: "el-icon-user",label: "测试一级菜单",path: "/test3",children: [{id: "103-0",icon: "el-icon-user",label: "测试二级菜单",path: "/third",children: [{id: "103-0-0",icon: "el-icon-user",label: "二级子页面",path: "/small",children: [],},],},],},],},],
};
const get = (obj) => {return new Promise((resolve, reject) => {setTimeout(() => {if (obj) {resolve(mockRoutes);} else {reject({});}}, 200);});
};export { get };

在src/register-route-store.js中的如下代码是进行真假路由数据切换的地方:

// import { get } from "./http/index.js";  //real routes fetched from platform
import { get } from "./mockRoutes.js";  //mock routes 

基于element-ui 搭建管理后台相关推荐

  1. Spring3.2.0-mybatis3.2.0 基于全注解搭建的后台框架-基础版

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: Spring3.2.0-mybatis3.2.0 基于全注解搭建的后台框架-基础版 没有什么不可能  之前一直用的是自 ...

  2. 撸一个基于VUE的WEB管理后台(一)

    最近需要一个BS架构的管理后台,对工作过程中产生的调研资料进行登记.查询和导出.我们的调研资料都是人工收集,每年的产生量大概也就是万级,用户人数也不过百,从需求上来看并没有什么架构压力,正好适合我这样 ...

  3. VUE element UI 搭建

    VUE的环境安装这里就不多说了,我们直接开始element UI的安装. 第零步:在自己的git仓库中,先新建一个项目 推荐使用开源中国的码云:Gitee - 基于 Git 的代码托管和研发协作平台 ...

  4. vue2 - 基于Element UI实现上传Excel表单数据功能

    一.项目场景 批量数据上传后台,需要从后台下载一个固定格式的 Excel表格,然后在表格里面添加数据,将数据格式化,再上传给后台,后台做解析处理,往数据库添加数据 二.实现功能展示 点击导入excel ...

  5. 基于Element ui 实现输入框只能输入数字并支持千分位

    实现效果 设置子组件 <template><el-inputref="money"v-model.trim="money":placehold ...

  6. axure element ui素材_【Axure分享】基于Element UI的Axure Web组件

    有一段时间没做过产品原型了,前一阵有一个web产品需要做原型,正好在搞前端,于是顺便把Element UI移植到Axure上,基本上实现了大部分的功能组件,部分过于繁琐的组件未实现. 自己觉得蛮满意的 ...

  7. 用vue(element ui)快速开发后台管理

    平时我们在用vue开发网站后台管理的时候.比如说要写管理文章的功能,要先去写列表页面,编辑页面,添加页面.另外还需要程序提供对应的增删改查接口 图片上传接口等等,那么有没有一种快速的方法.可以用程序来 ...

  8. element ui 电商后台商品属性管理页面

    电商后台商品属性管理 最近在做电商后台,电商商品中有个SKU值,类似于 服装的 "尺码""颜色""款式"等. 界面如下: 所用到的知识点如下 ...

  9. vue 前端显示图片加token_前端Vue3.0:从0到1手把手撸码搭建管理后台系统

    第1节 – 了解项目开发流程 手把手撸码前端 – 第1学时 了解产品从0到1的开发流程,产品经理.UI设计师.研发部.测试工程师 第2节 – 构建vue项目.代码仓库管理 手把手撸码前端 – 第2学时 ...

最新文章

  1. vue @click 赋值_vue 手写一个时间选择器
  2. 【原创】简单轻松浏览FTP
  3. 第二篇 Python图片处理模块PIL(pillow)
  4. Asp.Net SignalR - 简单聊天室实现
  5. Linux 基金会与 RISC-V 基金会合作推广开源芯片
  6. java删不了_java – 为什么我不能删除项目?
  7. ThinkPHP 3 的输出
  8. AOJ2025 Eight Princes
  9. 【软考】(五)网络互联设备
  10. MIMO系统信号检测之MMSE推论
  11. wordpress mysql缓存_WordPress 如何启用 Memcached 内存缓存来提高网站速度
  12. 嵌入式软件测试——1.简介
  13. 中国大学慕课第7周测验
  14. 货郎担问题java算法_经典算法(1)---货郎担问题
  15. 华为鸿蒙系统适配芯片,华为新平板参数曝光,高通骁龙870芯片加持,首发适配鸿蒙系统...
  16. 区块链学习2-合约开发
  17. cmd命令行切换目录
  18. java不区分大小写查找字符串
  19. 南郑县天气预报软件测试,汉中 高速公路环境气象监测系统 24小时自动化监测...
  20. 【图像识别与处理】图像相似度对比的几种办法

热门文章

  1. tcp 如何维护长连接
  2. iphone下拉菜单卡住了_为什么苹果手机把主菜单往下拉时就会卡死
  3. Vue.js前端开发实战总结(1)
  4. java.io.IOException: 远程主机强迫关闭了一个现有的连接
  5. 一文让你了解RFID标签芯片厂家有哪些?
  6. SSM框架搭建详细解析
  7. Asp.Net 汉字转(拼音)
  8. 二次型、特征值/向量、奇异值、特征值、奇异值分解、奇异值分解(SVD)原理与在降维中的应用
  9. 初中语文古诗词作者生平归纳
  10. 【matlab教程】02、拼接矩阵或向量