这是我参与更文挑战的第1天,活动详情查看: 更文挑战
前言
为什么要重新搭建一遍vue-element-admin
,我相信很多人平时工作,都是业务开发,没有关注到工程构建中,或者公司有专人搞架构,反正诸多原因...,而个人因为工作非必要,也是心有余而力不足;或者有优秀的项目时,拉取下来学习,感觉都会了,并没有动手尝试逐一搭建;或许很多人在面试的时候,需要!!!
这段话是我走完下面所有步骤,反过来写的,有以下收获:
- 工程搭建命令窗口不能选择,可使用
winpty vue.cmd create
方式 - 对
scss
配置和使用,解决版本问题 - vsCode、Prettier和Eslint规则检验之间的配合
- 动态路由的添加以及路由权限校验
- 动作(按钮)权限检验方式:指令和表达式
- layout组件群(布局组件集合)
- 基础主题色设置
- svg图标使用,并通过依赖合成雪碧图
- 登录token和用户信息处理(不适合单点登录)
- vuex使用,对modules进行合理的分配
展望:
- 多环境配置,以及模块打包优化
- CDN方式引入
- 一键打包部署到服务器 juejin.cn/post/687291…
进入主题
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,统一风格
-
格式化文档方式
-
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
即可使用。
- 踩坑:
- 安装出现问题
node-sass
安装可能会因为版本太高而失败,如果失败,通过npm uninstall xxx
卸载,重装低版本,如npm install node-sass@5.x --save-dev
; - 出现
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",
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;
}
- 动态换肤,下面这个好像比我说的明白,啊哈哈
panjiachen.github.io/vue-element…
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,如:
引入方式修改即可:
import * as pathToRegexp from 'path-to-regexp'
15、其他
Github:github.com/wwmingly/vv…
参考文档:panjiachen.github.io/vue-element…