搭建个人的后台模板(vvmily-admin-template)|8月更文挑战

541 阅读4分钟

这是我参与更文挑战的第1天,活动详情查看: 更文挑战

前言

为什么要重新搭建一遍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. 多环境配置,以及模块打包优化
  2. CDN方式引入
  3. 一键打包部署到服务器 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即可使用。

  • 踩坑:
  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",

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…