[Vue]组件二次封装时的总结
这篇文章中,我想以案例为主线,分析一下二次封装组件时的注意点,并且总结一下方法论,但我作为一个仅入行半年的新手前端,可能我的很多设计并不够好,因此也就当抛砖引玉了。
为什么要二次封装组件
- 因为原生的组件不能够完全满足开发需求....以
Vue
开发为例,目前国内比较常用的组件库是Element Plus
,它本身的组件库已经挺丰富的了,但是很多时候具体到实际开发中,组件库仍然不能满足一些细节上的要求,比如数据格式、样式等,每个项目都有其特殊性。
1. 封装文件上传
可能你会奇怪:不是有
ElUpload
[1]了吗?为什么还需要封装文件上传?这就涉及到针对于特定项目的细节问题了,详见下文。
需求
- 接口需要鉴权,请求时需要携带Token
- 上传文件走统一的接口,然后将上传接口的响应数据放到表单中
- 响应数据和
ElUpload
的默认数据格式不同 - 存在只能上传单个文件的情况,此时提交到表单中的数据应当是
Object
,而不是Array<Object>
- 有预览、删除、禁用等功能,并且这些权限可以外部自行控制
问题
- 首先,对于第1点和第2点,
ElUpload
是可以实现的,只需要配置http-requset
,让其调用自定义的上传方法即可。 - 而对于第3和第4点,
ElUpload
就完全无法满足了。ElUpload
定义了自己的文件格式:UploadFile
,而我们需要的是FileDto
格式,二者的格式声明如下。并且ElUpload
通过v-model
只能得到UploadFile[]
,哪怕只允许上传单个文件,而我们需要根据情况决定获得FileDto
或FileDto[]
。这两点成为我进行二次封装的直接原因。 - 对于第5点来讲,
ElUpload
提供了一些这方面的属性,如disabled
、on-preview
等,但其功能并不完全,比如无法禁用掉删除按钮,也无法控制上传按钮的显示与隐藏,因此我们需要自己来实现这些功能,这也是二次封装的原因之一。
tsinterface UploadFile { name: string; percentage?: number; status: 'ready' | 'uploading' | 'success' | 'fail'; size?: number; response?: unknown; uid: number; url?: string; raw?: File & { uid: number }; }
tsinterface FileDto { fileName?: string; fileSize?: string; fileUrl: string; md5?: string; }
- 首先,对于第1点和第2点,
解决思路
- 首先,对于最为麻烦的第4点,我打算让封装的组件(暂称
MyUpload
)暴露出2个v-model
:list: FileDto[]
和single: FileDto
,这样在外部就可以根据情况来决定使用哪个。 - 然后,对于第3点,我打算对于
ElUpload
的v-model
,(称为file-list
),仍然保持其UploadFile[]
的格式,但上传完成后更新list
和single
- 最后,对于第5点,我打算通过
<template #default>
和<template #file>
两个插槽,替换掉其上传按钮和文件列表样式,从而实现更细粒度的控制。 - 其实还有几个大问题,主要集中在回显时,但我在一开始并没有想到。如果想跟随我的思路一块走的话,下面这个“一些深层的问题”可以先不看,在下一节的内容中,随着封装的深入,这些问题将逐渐浮出水面,我也会一一解决。
- 首先,对于最为麻烦的第4点,我打算让封装的组件(暂称