vue组件封装技巧,如何对vue模块进行功能封装
如何对vue模块进行功能封装,vue组件封装技巧
当业务不断累加,导致原本干净整洁的代码越来越冗余,各种变量和注释已经让他人望而却步,往往又苦于重构带来的成本,导致诞生很多巨石应用。与其让自己或他人面临这种问题,不如我们一起来学习下,如何将代码更优雅的组织起来,前人栽树,后人乘凉。
我经常和别人强调,一定要做好设计,设计的目标是什么?个人理解是,增加代码的可塑空间,降低维护成本。
文档设计是必要的吗?
答案是肯定的,在做业务之前一定要做好设计,但究竟哪些是需要我们设计的呢?做好以下几点,轻松搞定前端文档设计:
- 需求目标是什么?
- 你是怎么理解需求的
- 实现方案是什么
- 关键节点的数据解构设计是什么
- 模块的作用
- 如何CRUD
- 新人拿到这个文档是否可以理解你的设计思路
很多时候大家是没有时间做设计的,但在开发之前这些是你必须要确认清楚的,尤其是对于新手来说,建议大家不要立刻开始开发任务,一定是要想清楚才动手。理想情况下70%设计(输出伪代码),30%的业务填充。好的领导一定会重视员工的成长和项目的未来的,如果有条件,就用文档把想法输出吧。
有了思路和方案,我们来看看怎么去把代码组织的更优雅吧,首先我们需要思考几个问题:
- 目录结构如何建设,理由是什么。
- 模块功能划分,是否遵循高内聚,低耦合的思想?
- 函数怎么设计,是否可移植可复用。
- 是否有清晰的注释说明
以上4点,我们在开发过程中,新建文件和函数时,要时刻注意,目标是让我们建设的工程,结构清晰,模块作用明确,各施其职,就像一排排整齐的水管。
vue组件封装技巧
- 提取公共常量
- 提取公共工具类
- 提取类型声明文件
- 单个vue组件封装
单个vue组件封装
组件拆分
将独立的功能拆成一个个组件,就像你看到一个网页设计稿,很容易把它拆成不同的div模块,相互协作拼装出来一个完整的网页一样,稍加练习,这对大家来说很容易做到。
例如:
数据模型
按照功能模块将数据封装成对象或数组
反面例子:
private pprMenuTemporary = []; // 正在拼装中的pprMenu,这个是为了解决处理过程中更新数组不刷新的问题
private entityName: Array<string> = []; // 试题和问题的中文名称,仅供显示用
private pprItem: any = {}; // 当前页面的核心数据,ppr对象
private hasError: boolean = false; // 是否包含错误,如果有错误,切换头部显示内容
private errorList: ErrorPprType = null; // 检错之后的列表(包含引擎和生词库的聚合)
private errorFormat: any = null; // 格式错误列表
private currentErrorNode: string = ''; // 当前聚焦的错误节点
正面例子(伪代码):
private pprInfo = {
MenuTemporary = [], // 正在拼装中的pprMenu,这个是为了解决处理过程中更新数组不刷新的问题
pprItem: any = {} // 当前页面的核心数据,ppr对象
}
private entityName: Array<string> = []; // 试题和问题的中文名称,仅供显示用
private errorInfo = {
hasError: boolean = false, // 是否包含错误,如果有错误,切换头部显示内容
errorList: ErrorPprType = null, // 检错之后的列表(包含引擎和生词库的聚合)
errorFormat: any = null, // 格式错误列表
currentErrorNode: string = '' // 当前聚焦的错误节点
}
初始化组件
从create到mounted,函数的执行应该是线性的,如果当前数据不影响界面渲染,可执行异步任务。例如:当你在做代码评审时,大部分总是从creat函数开始(也可能由其他函数开始)
剥离核心流程和附属流程(很重要)
明确当前组件的核心功能,核心功能应有一个明确的执行路线,就是组件的核心主流程,其他的附属流程都应该以引用或调用的方式出现,并加好注释。当我们不用去看附属流程的代码就可以轻松看懂业务流程,说明我们做的还不错。
例子:
private async getRawLibrary (errorMsg) {
if (errorMsg) {
// 1、解析返回的数据,获取依赖数据
const { words, format } = this.checkPaperResultDecode(errorMsg);
// 2、先把格式错误的数据存起来
if (Object.keys(format).length > 0) {
this.errorFormat = format;
}
// 2、如果有生词,需要查询生词库做相应的处理
if (Object.keys(words).length > 0) {
// 3、 扁平化处理数据
const wordsArray = this.delayerCandidateWords(words);
// 4、查询生词库,把只有一个音标的自动添加到对应的节点中,有多个音标的变成,可编辑项
await this.searchCandidateWords(wordsArray, words);
}
}
}
上面这个函数,一共做了4件事情,但是它的核心只是给errorFormat赋值,并且把words交给下一个处理函数。获取依赖数据、扁平化处理数据都是它的附属流程。
独立的内部交互机制
当前组件的核心业务流程,如非必要,仅作用于组件内部。如果需要外部运行环境,应在初始化时一起获取完毕
统一的数据入口
比如provide/inject,props接收等,如果props太多,建议封装成对象。除了props我们还应该提供一个setData方法,以便外部手动触发数据更新。
统一的数据出口
提供合适的数据给外部使用,当外部有这个需要时。data函数中的数据可以通过组件原型的方式获取到,我们还应该提供一个对应的getData的能力。
公共状态管理
合理的利用vuex和全局bus,二选一即可,别烂用。一般我们通过父子数据传递和vuex就足够了。用多了会造成心智负担。
外部交互的反馈
当和其他组件交互时,应给出合理的反馈,例如:当点击menu菜单时,应该把菜单的所在数组中的位置一并返回出去。
组卷内部格式校验
输入的数据格式是否符合要求
导出的数据格式是否统一规范
组件的销毁
事件委托和定时任务销毁
以上内容不是标准,仅仅是提供大家一个思路,一个完整的vue组件一定是与业务息息相关的,这里就不一一举例了。没有绝对的标准,只有优秀的思想和不同的实现。希望大家都可以写出优秀的代码。