本文的主要搭建一个基于vue-cli的一个后台管理系统的一个框架模板。大家如果有做过管理系统的,应该都会有如下几个功能:接口请求统一处理一些状态、权限管理、路由拦截、左边导航右边内容的布局等等一些功能。这个框架用到了Vue、vuex、vue-router、axios等技术栈、Ui用的是饿了么开发的一个基于Vue的框架,使用框架能大大提高开发的效率。

首先通过vue-cli来下载模板

//安装全局的vue-cli $ npm install vue-cli -g //下载模板 $ vue init yuanjie007/element-admin TestDemo(项目名字)

然后按照对应的提示的来操来就好了!!!

如果出现运行的出现Module build failed: Error: Cannot find module node-sass错误,这个一般是因为天朝的网络的原因,导致没有下载成功,代理去下载就好了,具体的去网上找方法吧!

小提示:
    用webpack我觉得有一个功能特别有用,那就是配置路径别名,这样子就不用再考虑什么相对路径了,所以我把src下的目录都配置别名,别名就是文件夹的名字,大家可以打开/build/webpack.base.conf.js里面的resolve属性来看下

目录的结构

├─build ----------------------------------------vue-cli的配置文件 ├─config----------------------------------------vue-cli的配置文件 ├─src │ ├─assets--------------------------------------存放静态文件(可变的) │ │ └─scss----------------------------------------存放全局scss变量,以及公共的样式文件,用sass-resources-loader引入 │ ├─components-------------------------------存放公共的组件 │ ├─config--------------------------------------全局的一些配置 │ │ │ index.js----------------------------------配置入口文件 │ │ │ menu.js----------------------------------左侧导航栏的菜单 │ │ └─interceptors-----------------------------全局的拦截器 │ ├─layouts--------------------------------------布局命名规范统一用Layout结尾大驼峰写法如UserLayout │ ├─plugins-------------------------------------存放插件 │ │ api.js-------------------------------------封装的API插件 │ │ axios.js-----------------------------------对axios的封装 │ │ indect.js----------------------------------全局的注入文件 │ │ directive.js----------------------------------全局的自定义指令 │ │ mixin.js-----------------------------------全局的mixin,通过indect注入 │ │ router.js-----------------------------------路由的插件 │ ├─routers--------------------------------------存放路由模块的文件 │ │ └─module----------------------------------------存放路由模块,index会自动遍历这个文件夹所有文件 │ │ index.js----------------------------------------路由文件的入口文件 │ ├─service---------------------------------------服务层 │ │ └─api----------------------------------------所有的api接口配置 │ │ └─module----------------------------------------api模块,index会自动遍历这个文件夹所有文件 │ │ index.js----------------------------------------api文件的入口文件 │ │ └─mock----------------------------------------mock(模拟接口数据) │ │ └─module----------------------------------------mock模块,index会自动遍历这个文件夹所有文件 │ │ index.js----------------------------------------mock文件的入口文件 │ ├─store-----------------------------------------存放vuex的模块文件 │ ├─utils------------------------------------------存放一些公共的工具 │ └─views-----------------------------------------存放的页面文件 └─static--------------------------------------------存放静态资源文件(不可变的) │ main.js-------------------------------------------主入口文件

接下来是我封装的一些功能

菜单栏(SideNavigation和HeaderNavigation):

这里主要说下左侧边栏的菜单配置,打开src/config/menu.js来看下格式:

export default [{ text: "菜单名字", icon: '图标', api: 'api接口', //我用他来校验是否有权限访问这个菜单 path: '/user', //路由 没有childs 则必填 route: {}, //路由的参数对象,选填 childs: [ //代表有下级菜单,只能两层 { text: '用户列表', icon: 'list', path: '/user' } ] }]

API请求(service/api)

如果要切换成真正的接口请在config/index.js下的AXIOS_DEFAULT_CONFIG:{mock: false}默认开发环境是用mock来搞的,生产环境默认真实地址

接口请求的库是axios,点击查看文档
config/interceptors/axios里面可以配置一些拦截,比如请求成功、请求错误、响应成功、响应错误等等。
我们可以在响应成功的时候处理一些特殊的状态码,比如未登录(401),没有这个接口(404)等等。

//响应成功的一些处理 export function responseSuccessFunc(responseObj){ //假如接口的数据格式如下: { code: 200, //状态码 message: '', //对应的提示文本 data: Array || Object | String //响应的内容 } let { data } = responseObj; let code = data.code; switch (code) { case 200: //假如200代表正常返回数据 return data.data; break; case 401: message.error("请登录!"); //弹框提示 并且跳转到登录页面 window.location.href = `${window.location.origin}/#/login`; return Promise.reject(data); break; default: let status = responseObj.config._code; //特殊code需要下发到业务方,就不用弹框提示 if (status) { if (!(status instanceof Array)) status = [status]; if (status.includes(code)) return Promise.reject(data); } Message.error(data.message); return Promise.reject(data); } }

然后在service/api/module下面添加对应的请求接口,可以按功能来划分模块,这样子也比较好找,来看下代码:

//比如这个是用户模块,新建一个user.js导入下面的代码 export default [{ name: 'index', //接口的名字 method: 'GET', //接口请求的方式 desc: '用户列表', //接口描述 path: '/admin/user/index', //接口路径 mockPath: '', //mock的地址,默认和path一样 params: { //要请求的参数,必须要填写,如果这里没有填,则不会携带参数 name: '', phone: '' } }] // service/api/index.js 会自动导入./module的所有文件,并且用文件名来做key

然后就可以在Vue的实例里面可以这样子调用我们刚添加的用户列表的接口:

this.$api['userIndex']({参数: '值'}, {axios的一些配置,比如header}).then(res=>{ //处理正常的逻辑 }, error=>{ //捕捉接口的错误 })

在没有Vue的实例也可以用,直接引入plugins/api

//比如在主入口main调用接口 import API form 'plugins/api'; API['userIndex']({参数: '值'}, {axios的一些配置,比如header}).then(res=>{ //处理正常的逻辑 }, error=>{ //捕捉接口的错误 })

大家可能会有点疑惑究竟是怎么搞的,应该有点懵逼了,别着急,去看下plugins/api代码应该就能懂了,我就不贴代码了,都有注释的。然后通过plugins/inject注入到Vue的实例里面:

import api from "./api"; export default { //通过vue提供的install插件接口 install: (Vue)=>{ Vue.prototype.$api = api; } } //在主入口文件main.js 添加下面的代码 import Vue from 'vue' import inject from 'plugins/inject' Vue.use(inject)

Mock

  模拟接口数据,在service/mock/目录下,详细的语法规范请移步到mock的官方文档查看Mock文档

我在service/mock/util.js文件里添加了几个工具方法:

名称 描述 返回值 默认值
Mock Mock的实例方法 具体的详细方法请移步官方文档 -
resSend 正常响应接口的数据 {code: 200, data: 任何类型, message: ‘’} {code: 200, data: null, message: ‘success’}
resSendList 响应列表的接口数据(包含分页) {current_page: 1,from: 1,last_page: 1,per_page: 15,to: 3,total: 15,data: [{}]} 如果你真正的接口不是这些,可以改成你们的,这里只是做一个演示 {current_page: 1,from: 1,last_page: 1,per_page: 15,to: 3,total: 15,data: [{}]}

路由(router)

路由也可以和api接口一样划分模块,里面的配置都是和vue-router一样的。比如要搞一个用户管理(user)
在```router/module/下面新建一个user.js

//这里用到了异步加载,可以根据需求来引入 const User = r => require.ensure([], () => r(require('views/user/Index')), 'user') const AssignRole = r => require.ensure([], () => r(require('views/user/children/AssignRole')), 'user') export default { path: 'user', //用户跳转的路径 component: User, //对应组件 meta: { auth: false, //校验 默认为true,为false这不用校验 bread: ['用户管理'] //生成面包屑导航 => 首页 / 用户管理 }, children: [{ //子路由 path: '', name: 'user', meta: { bread: ['可以多个', {url: '/user', text: '用户列表'}] //如果为Object,这可以点击跳转 } }] } // router/index.js 会自动导入./module的所有文件

meta属性说明

名称 类型 描述 默认值
auth Boolean 路由鉴权,设置为false则鉴权 true
layout String 对应layouts里面的布局,如要用BlankLayout这个布局,只需要写blank就好了 general
bread Array 面包屑导航的数据,如果数组的值有两种Object和String, Object格式:{ text: ‘用户管理(显示的文本)’, url: ‘user(跳转的url)’ }; String: ‘用户管理’ -

可以在config/interceptors/router设置路由的拦截器

//路由鉴权 export function beforeEach(to, from, next) { //meta 带有auth: false 就是不用验证的 if (to.meta.auth === false) { next() } else { //验证是通过localStorage的用户信息来保存的 if (!localStorage.user) { next('/login') return false } else { next() return false } } next() }

store(Vuex)状态管理

这个就没有什么好说的了,照着vuex文档撸就行了。

绑定在Vue原型链上的api方法

这些都是在plugins/inject.js里面注入的

$config //在config/index 里面的配置
$api 	//api的请求方法 详细请见上面的 API请求(service/api)
$auth   //权限列表 是在登录之后请求回来的权限列表,详见views/login/Login.vue下的getPermissionList方法 有保存到localStorage

获取上面的属性如 配置($config): this.$config 就好了

其他

1.plugins/mixin 有对localStorage存储的封装

计算属性(computed):

windowSize 窗口的大小,只要窗口变化就会更新, 窗口监听是在components/HeaderNavigation.vue 下面的changeWindow方法,可以用这个值来做页面的响应式

方法(methods):

//检查传过来的api是否有权限,参数为String|Array 数组的话只要有一个有权限就返回true, api的前缀都是/api/admin/,具体怎么认证,可以自行修改它的逻辑 checkAuth(["user/update","user/delete"]) //获取值 getLocalStorage('key', true) //第一个是key,第二个是否要转成Object //存储值 setLocalStorage('key', data) //会把Array,Object 转换成String
  1. views 页面的组件都写到这里面
  2. 全局的指令 v-auth 用来做按钮级权限,具体的权限认证逻辑可自行修改
//如果有权限就会显示,没有就会把他移除。注意api一定要''用单引号括起来 <el-button type="primary" v-auth="'user/add'">添加用户</el-button>

其他的应该没有什么了,大家可以自行扩展吧~~~

最后在分享一篇文章https://juejin.im/post/5b29c3bde51d45588d4d7110我就是看了这篇文章以后,然后根据自身的一些经验搞出来的,肯定会有很多的不足,我会去慢慢的完善它,比如加mock等等。

排版有点乱,将就下
逃~~~~~~