[TOC]
## 前言
通过本问将看到我在vue的项目中,进行的一系列的项目优化,然后看到不同的维度将这些点进行分类。
这里更多的指的是设计考虑的思路,是大纲,暂不涉及实际代码。
## 项目架构
### 分模块设计思想
在接到项目之后,首先将store,router,xhr的对应三个部分分别分子模块,每个子模块的划分维度有所差别。
- 其中store划分modules划分维度是数据关联性,由于store本身支持modules的组合,而且使用是混合在一起的,所以我们还是会在index中将模块进行混入的。
- 其中router是按照业务进行分模块的,或者说是按照页面维度分的,每个一级路由分一个路由模块,二级路由为页面名称,其中将一级路由设置为文件夹名称,二级路由路径与页面名称同名,为了简化这部分,一级路由的名称定为‘scope’,而且为了同时支持懒加载和优化引入组件的写法,写了_import的优化方法,可以批量按照文件名引入对应的组件,在生产环境将进行路由代码分割。然后不同模块也是最后汇总到router的modules中。
- 其中xhr的部分按照后端的微服务进行拆分模块,方便查看和维护。按照后端的接口层次再决定是否划分二级对象属性,其中暴露出来的方法与后端同名,后续也是决定采用easymock进行批量生成api方法来优化这部分手写代码的工作。考虑到几乎没有一个页面或者组件会用到多余两个的api微服务请求,所以这就决定了我在index.js中并没有收集聚合每个业务的api,而是选择开发时按需加载。而对于通用性比较高的api,我一方面会定义在index.js中,另一方面会把这部分数据暴露在vuex中来达到目的。
- 额外介绍,除了以上三个,我针对src根目录也设置了过滤器的分业务模块实现方案。这部分由于各个业务耦合情况比较少,所以也是仅仅针对核心的工具过滤器暴露在index.js中,其他的都是按需引入。
### 业务内公共组件
与有的同学考虑不同的是,我在写一些组件的时候,针对业务性比较强,但是针对当前业务公用的一些拆分组件会定义在每个业务的components目录下,而不是放在src/components,我称之业务内公共组件。
### 业务内枚举 与 全局枚举 
其实很多时候会遇到枚举数据,或者是后端定义好的,或者是前端定义好的,或者是接口请求的但是基本不做更改的。也许枚举字段少的也还好,但如果一个数据项有超过十个枚举项,有超过2个页面使用的时候,你应该考虑的是单独的放在枚举字典文件中去维护。
那么首先,我是建议基于这个业务的枚举建在业务的根目录下新建一个enum的js枚举文件,单独用来承载业务中的枚举。但较多时候会有一些比较让人烦恼的部分:
1 业务中的枚举发现另外的页面中也有用,不单单属于这个一级业务页面。那么你可以这样考虑下:首先肯定是维护一份数据的,那么维护在哪里,如果是核心业务,那就维护在全局枚举仓库,然后业务中进行按需引入或者改装。如果是周边业务,偶尔用下,我个人觉得维护在业务中的枚举是比较好的。
2 枚举与过滤器与字段翻译的关系。其实枚举字段不仅仅是用于做枚举的,还必然的会充当一些下拉框,显示值的遍历来源,也可以当做字段翻译的翻译来源,同时还可以当做我们一些业务字段的过滤器。这部分理解好之后,对于我们优化整理项目中的业务数据类型有着极大的好处。
3 全局枚举业务过滤器,通用性过滤器,当然这些过滤器功能除了按照基本的部分,还会按照业务中收集到的部分进行业务过滤器的维护。同时也作为对应的方法来获得对应值转换值的语法,一者两得。
### common组件
- 纯ui组件,elementui组件进行进一步的封装,按照其官方的维护方式进行自己项目需求的一些分类。
- 布局内基本布局组件,这里面包括了页面架构,菜单,顶部,主题页面。
- 可分解于任何页面任何位置的特征业务组件,支持其展现到任何位置任何页面中,只要求其对应的业务数据要求即可。
- 功能性组件,包括图片上传,自定义的模态框
### theme
为了维护基本的风格,设置了一些基本的主题变量,然后针对elementui的核心组件修改器风格颜色。
### axios拦截
针对axios的部分进行请求前后拦截,针对特定状态码进行翻译,在这个设置中进行vuex必要的接口token必要性的验证以及引入提示组件进行必要的接口提示。
针对业务的整合需求,进行接口的串联、并联的请求优化。
### mixins
将常用的优化方法进行mixins进行混入。
## 典型代码段优化
### 用数据做逻辑,减少标签的显示控制
看到很多前端会根据数据的某个字段,然后写v-if 决定这个标签是否显示,然后不是这个字段,另外一个显示。建议在不管是对象还是数组的显示控制中,直接根据需要的数据进行数据改装,不用多条件判断类似的组件渲染。这种代码简单的可以用一个标签承载,内容的显示区别简单的可以用三目,复杂的就应该在js方法中进行改造完之后或者过滤器实现。
```
<span v-if="sex===male" >男</span>
<span v-else >女<span>
```
### 挥之不去的静态复制写法
vue提供了良好的数组循环和对象循环的方法,在我们实现类似的页面需求的时候,不建议再和之前一样,写很多维护性不强的页面列表了。把它用一个数组维护,然后v-for循环实现,对于因为大量的这种代码占据篇幅的话,说明还是 没有很好的理解vm的含义。
```
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3 </option>
```
### 除了if,else想不到其他逻辑方式
然后就看到一大波人会if,age===0,判断,else if 等等。其实除了这些你还有switch,对象属性字面量方式,switch方式,等等。不要让if,else的嵌套循环成为我们写代码的唯一方式。
```
<option value='0'>0</option>
<option value='18'>未成年</option>
<option value='60'>老年 </option>
```
## 待更新中
                    
        - 前端工程化
 - 架构总纲
 - 001
 - 美团技术架构
 - 前端工程化说明
 - 历史背景说明
 - 架构说明
 - 前端工程化技术栈
 - 技术文档说明
 - 功能模块说明
 - 前端模块管理器简介
 - 框架对比分析
 - vue&react&ng对比分析(一)
 - vue&react&ng对比分析(二)
 - vue&react&ng对比分析(三)
 - 工程化专题系列
 - 需要解决的问题
 - 001
 - 002
 - 003
 - 常见代码错误
 - jslint中常见的错误
 - css规范常见错误
 - html规范常见错误
 - 工程化目录
 - 工程化初始化
 - 项目构建流程
 - 项目打包优化
 - 上线与迭代注意事项
 - 前端部署发布
 - jetkins部署
 - 部署需求整理
 - 前端监控
 - 工程化实践指南
 - dock持续部署
 - 系列文章
 - 插拔式前端的设计
 - 其他实践
 - 工程化的前端管理
 - 宋小菜借鉴
 - 大前端团队介绍
 - 人员组成
 - 人员发展
 - 研发流程
 - 任务分类
 - 前端基础建设与架构
 - 技术栈以及技术方案
 - 业务目录大纲
 - 前端大纲
 - api管理
 - 后端api工具
 - 前端easymock
 - api拦截与代理
 - api优化
 - api请求时长策略设计
 - 前端架构专题
 - 架构专题一
 - 产品原型对接
 - 与ui对接
 - 图片专题
 - 图片工程化大纲
 - 图片优化
 - 图标字体
 - 图标字体vs雪碧图
 - 工程化的前端矩阵
 - 蚂蚁金服前端矩阵分享
 - BFF架构
 - 概念解析
 - 前端脚手架
 - 初始化项目
 - 个性化配置
 - 部署与发布
 - 性能优化专题
 - http专题
 - https常识
 - http优化1
 - http优化2
 - http优化3
 - http缓存
 - 常规web性能优化攻略
 - 性能优化大纲
 - 样式优化
 - js优化
 - 第三方依赖优化
 - 代码分割优化
 - 图片优化
 - 打包优化
 - 服务器优化
 - 缓存优化
 - 交互优化
 - pc事件优化
 - 手机事件优化
 - 推荐文章
 - 01
 - 前端安全专题
 - 前端安全大纲
 - 前端第三方库
 - seo优化
 - web框架的对比
 - 001
 - 学习资源
 - 珠峰前端架构
 - npm教程
 - npm入门
 - cnpm入门
 - cnpm搭建
 - 你该知道的js模块
 - browserSync
 - opn
 - js-cookie
 - npm-script进阶
 - 入门篇
 - 进阶篇
 - 高阶篇
 - 实践篇
 - yarn入门
 - nodejs教程
 - axios&&fetch
 - xhr
 - axios
 - fetch
 - babel专题
 - babel入门
 - profill入门
 - nodejs入门
 - 快速入门
 - 大纲介绍
 - node基础
 - global obj
 - assert断言
 - procss-进程
 - child_process子进程
 - cluster集群
 - console控制台
 - crypto-加密
 - dgram-数据报
 - dns-域名服务器
 - error-异常
 - events-事件
 - global-全局变量
 - http-基本协议
 - https-安全协议
 - modules-模块
 - os-操作系统
 - path-路径
 - querystring-查询字符串
 - readline-逐行读取
 - fs-文件系统
 - net-网络操作
 - 命令行工具
 - 内存泄露
 - 代码的组织与部署
 - 异步编程
 - orm模块
 - 异步编程解决方案
 - node-lessons
 - 环境准备
 - nodejs实践
 - 项目搭建
 - 异步优化
 - 创建web和tcp服务器
 - 终端问答程序
 - 爬虫系统
 - mongleDb
 - mongoDB简介
 - 基本使用
 - 实用技巧
 - 汇总001
 - 饿了么后台搭建
 - nodejs干货
 - 沪江基于node的实践
 - 苏宁基于nodejs优化
 - 基于nodejs开发脚手架
 - 书籍干货
 - 深入浅出nodejs
 - 异步I/O(一)
 - gulp教程
 - gulp入门
 - gulp常用插件(1)
 - gulp常用插件(2)
 - gulp创建目录
 - 经验普及贴
 - webpack教程
 - webpack入门
 - 简单入门
 - entry配置
 - output配置
 - 插件使用01
 - 插件使用02
 - loader使用
 - dev-server介绍
 - 构建css
 - css模块化
 - 使用less和sass
 - 构建图片
 - 引入字体
 - babel配置攻略
 - eslint
 - 001
 - webpack进阶
 - 分不同文件检出
 - 优化打包大小
 - 优化打包速度
 - 自定义配置
 - 单页以及多页如何配置
 - 优化实践
 - 文章导读
 - 001
 - 优化指南
 - 参考列表
 - webpack4
 - 多入口程序构建
 - 参考教程
 - 项目实践
 - 环境区分
 - 常见问题
 - 解读webpack
 - 从vuejs权威指南中解决
 - 深入浅出webpack
 - rollup
 - 入门
 - parcel
 - 入门篇
 - express教程
 - nuxt教程
 - 入门
 - 基本入门
 - koa教程
 - koa基本入门
 - koa开发注意事项
 - koa实践指南
 - 关于路由
 - koa优化指南
 - 001
 - Vuejs
 - vuejs入门系列
 - vue-cli入门
 - vue2基本认识
 - vuejs入门教程
 - 样式绑定
 - vuex入门学习笔记
 - vue组件生命周期
 - 组件的使用
 - vue-router入门
 - vue-filter
 - 计算属性使用
 - 开发注意事项
 - mixins
 - 组件通讯
 - vuejs进阶
 - 进阶资源
 - router进阶
 - 官网介绍
 - 前进与后退优化
 - keep-alive基本使用
 - keep-alive原理详解
 - 钩子函数进阶
 - 计算属性&监听&方法
 - vue服务端渲染技术
 - 项目实践之路
 - 实践大纲
 - 插槽专题篇
 - vue-cli升级
 - 进阶入门
 - vuejs架构
 - nuxt
 - vuejs项目实践
 - vue实践常见问题
 - 001
 - 002
 - 003
 - 004
 - 005
 - 改造api参数探索
 - 007
 - 008
 - 009
 - 010
 - 项目技术栈
 - vue性能问题以及优化方案
 - vue-spa应用的理解
 - vue-ssr的部署与使用
 - 滴滴出行实践案例
 - 2.0重构
 - vue-element-admin实践
 - 准备工作
 - 菜单设计
 - 权限设计
 - 依赖模块
 - vue-betterScroll
 - 性能优化懒加载
 - 京东组件实践
 - vue2项目小结
 - vue探索与实践
 - 去哪实践
 - 介绍
 - 饿了么项目实践
 - 项目解析
 - vue骨架屏实践
 - vue生态推荐
 - ui框架
 - elementUI
 - 001
 - 002
 - VUE-material
 - vant-ui
 - 解读入门
 - iview
 - 使用问题汇总
 - vux
 - mint-ui
 - loadmore
 - vue资源导航
 - vueconf
 - 源码解读
 - vm
 - 双向绑定
 - 基本原理
 - 数组双向绑定
 - 报错机制
 - 封装方法
 - 运行环境
 - 入门
 - 指令
 - vue-router解读
 - util
 - vue-props
 - 流程逻辑
 - 推荐文章
 - 源码解读
 - 文章导读
 - 001
 - vuejs实战
 - 基础篇
 - 进阶篇
 - 实践篇
 - 面试专题
 - angularjs教程
 - angularjs入门系列
 - 基本入门
 - ng2入门
 - ng进阶
 - ng项目实践
 - 源码解读
 - typescript
 - reactjs教程
 - reactjs入门系列
 - react的基本入门
 - react组件
 - virtalDom认识
 - react-cli入门
 - react组件的生命周期
 - 基本知识点
 - react-router教程
 - react进阶
 - 基本实践
 - react加载性能优化指南
 - react属性封装
 - 进阶45讲
 - 01概述
 - 02jsx
 - 06高阶组件&函数子组件
 - contextApi
 - react-router
 - 入门章节
 - 进阶
 - 高阶组件
 - react进阶组件
 - 基本介绍
 - render props
 - render props的封装
 - render props getter
 - react-native入门
 - 源码解读
 - 001
 - 002-reactDemo
 - 参考教程
 - 参考教程1
 - 了解react-hooks
 - ui框架
 - pc端ui框架推荐
 - 项目实践
 - weatherApp
 - 001
 - 002
 - 不同生命周期使用场景
 - react项目结构和组件的命名
 - 常见问题解答
 - 参考书籍
 - react全栈
 - 前言
 - react与redux进阶
 - 常见误解
 - 反模式
 - react设计模式与最佳实践
 - 7美化组件
 - 7.2行内样式
 - 7.4css模块
 - 深入react技术栈
 - react学习手册
 - 序
 - mobx教程
 - 入门
 - 大佬推荐
 - 001
 - react面试
 - 001
 - linux教程
 - linux入门
 - 基本入门
 - 文件管理
 - 文件传输
 - 文档编辑
 - 磁盘管理
 - 磁盘维护
 - 网络通讯
 - 系统管理
 - 系统设置
 - 备份压缩
 - 设备管理
 - 查看系统信息
 - linux其他
 - webhook
 - rsync入门教程
 - ssh免登陆设置
 - 安装nodejs
 - nginx教程
 - 入门教程
 - 安装
 - 基本配置
 - 服务基本使用
 - 高性能nginx
 - 001
 - pm2教程
 - shell教程
 - 入门大纲
 - echo命令
 - 参考文献
 - linux常用命令2
 - linux常见问题
 - 001
 - python
 - 入门教程
 - 机器学习
 - 准备工作
 - 服务器常识
 - tomcat
 - 入门常识
 - iis
 - redis教程
 - 入门第一篇
 - redis进阶
 - 项目实践
 - redis使用问题
 - mongleDB
 - 入门
 - 使用进阶
 - 项目实践
 - 常见问题
 - electron
 - 入门系列
 - 前言
 - 小程序
 - 入门
 - 准备工作
 - 路由
 - 参考文档
 - 001
 - 小程序开发--双路视频调研
 - 准备工作
 - 参考资源
 - 参考网址
 - docker
 - 入门
 - 基本认识
 - 安装与使用
 - docker安装nginx
 - docker安装jetkins(1)
 - docker部署jenkins(2)
 - 进阶
 - 实践总结
 - docker群分享
 - docker部署前端应用
 - 文章导读
 - docker其他
 - 网络安全
 - 入门
 - 大纲
 - 项目解析
 - schoolpal.web
 - 功能模块大纲
 - 目录结构大纲
 - 前端国际化
 - 国际化方案
 - 其他
 - bower入门教程
 - weex
 - 入门
 - memcached
 - 入门
 - sails
 - 入门
 
