🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] 为什么要重新搭建一遍`vue-element-admin`,我相信很多人平时工作,都是业务开发,没有关注到工程构建中,或者公司有专人搞架构,反正诸多原因...,而个人因为工作非必要,也是心有余而力不足;或者有优秀的项目时,拉取下来学习,感觉都会了,并没有动手尝试逐一搭建;或许很多人在面试的时候,需要!!! 这段话是我走完下面所有步骤,反过来写的,有以下收获: 1. 工程搭建命令窗口不能选择,可使用`winpty vue.cmd create`方式 2. 对`scss`配置和使用,解决版本问题 3. vsCode、Prettier和Eslint规则检验之间的配合 4. 动态路由的添加以及路由权限校验 5. 动作(按钮)权限检验方式:指令和表达式 6. layout组件群(布局组件集合) 7. 基础主题色设置 8. svg图标使用,并通过依赖合成雪碧图 9. 登录token和用户信息处理(不适合单点登录) 10. vuex使用,对modules进行合理的分配 展望: 1. [CDN方式引入](https://www.kancloud.cn/book/vvmily_king/vvmily/preview/cdn%E5%BC%95%E5%85%A5%E9%85%8D%E7%BD%AE.md) 2. [一键打包部署到服务器](https://juejin.cn/post/6872914108979609614#heading-1) ### 1、检查 vue-cli版本 执行命令 vue -V ,如果是全局安装1.x或者2.x,需要先卸载 `npm uninstall vue-cli -g` ,后安装 `npm install -g @vue/cli` ### 2、创建项目 vue create vvmily-admin-template 或者 vue ui 如果键盘上下键选择不起作用,官方提供方式:winpty vue.cmd create vvmily-admin-template 注:vvmily-admin-template是项目名称,可随意命名。 检验选择:ESLint + Prettier ### 3、配置 Eslint + VsCode,统一风格 * **格式化文档方式** ![](https://img.kancloud.cn/02/73/0273146a013d32ad6f3e876e154453a8_609x127.png) * **vsCode编辑器 setting.json文件配置** ``` "editor.formatOnSave": true, // 保存立即更改 "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, // eslint "eslint.options": { "configFile": ".eslintrc.js"// eslint的配置文件 }, "eslint.validate": [ "javascript", "javascriptreact", "vue"], "eslint.autoFixOnSave": true ``` * **项目 .eslintrc.js 配置** ``` module.exports = { root:true, parserOptions: { parser:'babel-eslint', sourceType:'module',    }, env: { browser:true, node:true, es6:true, }, // extends参考: https://cn.eslint.org/docs/user-guide/configuring#specifying-environments extends: [ 'plugin:vue/recommended', 'eslint:recommended' ], // 代码风格 rules: { // ... 自定义规则,文档参考: // https://github.com/vuejs/eslint-config-vue // https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/README.md } } ``` ### 4、项目环境配置 * **多环境配置** * **webpack优化** * **CDN引入** ### 5、引入 Element-UI ``` importCookiesfrom'js-cookie' importElementfrom'element-ui' import'element-ui/lib/theme-chalk/index.css' importenLangfrom'element-ui/lib/locale/lang/en'// lang i18n Vue.use(Element, { size:Cookies.get('size') || 'medium', // set element-ui default size locale:enLang// 如果使用中文,无需设置,请删除 }) ``` ### 6、scss预处理 `vue-loader`可以解析 css预处理,不用配置,直接安装 `npm install node-sass sass sass-loader --save-dev`即可使用。 * **踩坑1:** 1. 安装出现问题`node-sass`安装可能会因为版本太高而失败,如果失败,通过 `npm uninstall xxx`卸载,重装低版本,如 `npm install node-sass@5.x --save-dev `; 2. 出现 `inport 'xxx.scss'`报错,同样是因为 `sass-loader`安装版本太高,可通过 `npm uninstall xxx`卸载,重装低版本,如 `npm install sass-loader@6.0.7 --save-dev ` 本项目安装 ``` "node-sass": "^5.0.0", "sass": "^1.35.1", "sass-loader": "^6.0.7", ``` 截止以上,可以正常运行,可发现sass警告,看个人是否能接受。 * **踩坑2:** 最近发现一个警告,网上一查,说是版本太低? ![](https://img.kancloud.cn/48/d7/48d78f7fa9ba5ea7797bca2450c00741_392x167.png) 重新安装高版本的`npm i sass-loader@8.0.0 -D `,好家伙,这个警告确实不见了,但是又有问题了,一堆警告,虽然不影响使用,但是影响心情啊 ![](https://img.kancloud.cn/9d/51/9d519c940d1676ab520fbff66c13b577_1148x669.png) 解决方法:把`"sass":"^1.35.1"`版本号变为`"sass":"~1.32.6"`。 备注:`package.json`中`^` 和 `~` 区别如下 `^` :`^1.35.1`,则会安装 `1.x.x`最新版本,不会升级到 `2.0.0`; `~`:`~1.32.6`,则会安装 `1.32.x`最新版本,不回升级到 `1.33.0`。 ### 7、图标引入 * 安装依赖 `npm install svg-sprite-loader -D`,将svg图片合成雪碧图,并在`vue.config.js`中配置一下依赖: ``` chainWebpack(config) { config.module.rule('svg').exclude.add(resolve('src/icons')).end() // 将该文件排除在外,比如防止url-loader等处理 // svg-sprite-loader将svg图片合成雪碧图 config.module       .rule('icons')       .test(/\\.svg$/)       .include.add(resolve('src/icons'))       .end()       .use('svg-sprite-loader')       .loader('svg-sprite-loader')       .options({ symbolId:'icon-[name]'       })       .end() } ``` * svg图标整合在文件 `icons/svg`下, * 图标和公共组件SvgIcon整合到`icons/index.js`,如下: ``` importVuefrom'vue' importSvgIconfrom'@/components/SvgIcon' Vue.component('svg-icon', SvgIcon) // 全局注册 constreq = require.context('./svg', false, /\\.svg$/) constrequireAll = requireContext\=>requireContext.keys().map(requireContext) requireAll(req) ``` ### 8、更换主题色和动态换肤 * 主要利用scss的:export方式 ``` import variables from'@/styles/element-variables.scss' conststate = { theme:variables.theme } ``` ``` // element-variables.scss :export {   theme: #ccc; } ``` * 动态换肤,这个好像比我说的明白,啊哈哈 https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/theme.html#%E5%8A%A8%E6%80%81%E6%8D%A2%E8%82%A4 * 如果你只是想简单修改一下基本(主题)颜色,通过改变`element-variable.scss`文件变量,并且在main.js中引入,并且把默认主题文件`import 'element-ui/lib/theme-chalk/index.css'`去除,具体如图: ![](https://img.kancloud.cn/55/22/5522bd9dabe675587894cf8591b52cb0_1914x743.png) * 如上图配置复杂的个性化自定义主题,可前往[自定义主题](https://element.eleme.cn/#/zh-CN/theme)配置,下载,引入即可。 ### 9、引入 路由 Vue-Router * **路由分两类,是否需要通过权限检验** constantRoutes路由,如:登录,注册,404,302等一些页面,是不需要权限检验 asyncRoutes路由:存放权限校验路由,通过router.addRoutes(vue2.2.0以后)动态添加 ### 10、配置 Vuex ### 11、布局Layout ### 12、登录页面开发 * 思路:通过账号密码请求登录Api,从而拿到token ### 13、权限校验 * 登录成功获取token,则进行权限校验,否则重置到登陆页面 * 检验方法:路由钩子`router.beforeEach()`和动态添加路由`router.addRoutes()` ``` router.beforeEach(async(to, from, next) => { const hasToken = getToken() // 获取token if (hasToken) { // 当token存在,处理 if (to.path === '/login') { next({ path:'/' }) // 进入首页      } else { // 用于请求userInfo信息,且只(包括刷新)执行一次 // 关键:可通过任意userInfo等其他值,作为判断,如:userInfo.userId consthasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next()        } else { try { const { roles } = awaitstore.dispatch('user/getInfo') // 实际更多的是:accessRoutes应该得到asyncRoutes配置路由和后端Api返回的路由的并集 // 这里是通过用户角色 roles,与 accessRoutes路由中 meta.roles 进行匹配 const accessRoutes = awaitstore.dispatch('permission/generateRoutes', roles) router.addRoutes(accessRoutes) // 动态添加路由 next({ ...to, replace:true })          } catch (error) { awaitstore.dispatch('user/resetToken') next(`/login?redirect=${to.path}`)         }       }     }   } else { if (whiteList.indexOf(to.path) !== -1) { next()      } else { next(`/login?redirect=${to.path}`)      }   } }) ``` ### 14、公共组件封装 * 面包屑组件 Breadcrumb.vue 由于版本问题 `pathToRegexp.compile()`方法可能报undefined,如:![](https://img.kancloud.cn/8f/8b/8f8bde46ea81cd3ee115c7546c25f300_969x146.png) 引入方式修改即可: ``` import * as pathToRegexp from 'path-to-regexp' ``` ### 15、打包优化 * 优化一: 执行`npm run build`,可能会报错,是缺少依赖了 ![](https://img.kancloud.cn/df/b6/dfb6cb878460e0ae22d94c739ac56f75_641x87.png) 安装即可:`npm install script-ext-html-webpack-plugin -D` * 优化二 安装`npm install -D terser-webpack-plugin@4.2.3 `,[传送](https://webpack.docschina.org/plugins/terser-webpack-plugin/)。 注意版本,默认安装可能是`5.x.x`,这是适配webpack5的,如发现以下错误,重新安装4.x.x即可 ![](https://img.kancloud.cn/37/6a/376ae69a9e336a8df6bb36a8c17bb9ee_665x161.png) ``` // 引入 const TerserPlugin = require('terser-webpack-plugin') // 配置 ... configureWebpack: { optimization: process.env.NODE_ENV === 'production' ? { minimizer: [ new TerserPlugin({ terserOptions: { ecma: undefined, warnings: false, parse: {}, compress: { drop_console: true, drop_debugger: false, pure_funcs: ['console.log'] // 移除console } } }) ] } : {}, resolve: { alias: { '@': resolve('src') } } }, ``` * 优化三 **打包后部署到环境,icon偶尔会出现乱码问题** 使用`node-sass`,替换` "sass": "1.26.2"`, 解决方法,执行以下两步  `set SASS\_BINARY\_SITE=https://npm.taobao.org/mirrors/node-sass/` // 解决安装不成功问题  `npm install node-sass@4.14.1 -D` 注意:`"node-sass": "^4.14.1"`,有可能安装不成功 ### 16、其他 Github:https://github.com/wwmingly/vvmily-admin-template 参考文档:https://panjiachen.github.io/vue-element-admin-site/zh/