Skip to content

[Vue]组件二次封装时的总结

这篇文章中,我想以案例为主线,分析一下二次封装组件时的注意点,并且总结一下方法论,但我作为一个仅入行半年的新手前端,可能我的很多设计并不够好,因此也就当抛砖引玉了。

为什么要二次封装组件

  • 因为原生的组件不能够完全满足开发需求....以Vue开发为例,目前国内比较常用的组件库是Element Plus,它本身的组件库已经挺丰富的了,但是很多时候具体到实际开发中,组件库仍然不能满足一些细节上的要求,比如数据格式、样式等,每个项目都有其特殊性。

1. 封装文件上传

可能你会奇怪:不是有ElUpload[1]了吗?为什么还需要封装文件上传?这就涉及到针对于特定项目的细节问题了,详见下文。

  • 需求

    1. 接口需要鉴权,请求时需要携带Token
    2. 上传文件走统一的接口,然后将上传接口的响应数据放到表单中
    3. 响应数据和ElUpload的默认数据格式不同
    4. 存在只能上传单个文件的情况,此时提交到表单中的数据应当是Object,而不是Array<Object>
    5. 有预览、删除、禁用等功能,并且这些权限可以外部自行控制
  • 问题

    1. 首先,对于第1点和第2点,ElUpload是可以实现的,只需要配置http-requset,让其调用自定义的上传方法即可。
    2. 而对于第3和第4点,ElUpload就完全无法满足了。ElUpload定义了自己的文件格式:UploadFile,而我们需要的是FileDto格式,二者的格式声明如下。并且ElUpload通过v-model只能得到UploadFile[],哪怕只允许上传单个文件,而我们需要根据情况决定获得FileDtoFileDto[]。这两点成为我进行二次封装的直接原因。
    3. 对于第5点来讲,ElUpload提供了一些这方面的属性,如disabledon-preview等,但其功能并不完全,比如无法禁用掉删除按钮,也无法控制上传按钮的显示与隐藏,因此我们需要自己来实现这些功能,这也是二次封装的原因之一。
    ts
    interface UploadFile {
      name: string;
      percentage?: number;
      status: 'ready' | 'uploading' | 'success' | 'fail';
      size?: number;
      response?: unknown;
      uid: number;
      url?: string;
      raw?: File & { uid: number };
    }
    ts
    
    interface FileDto {
      fileName?: string;
      fileSize?: string;
      fileUrl: string;
      md5?: string;
    }
  • 解决思路

    1. 首先,对于最为麻烦的第4点,我打算让封装的组件(暂称MyUpload)暴露出2个v-modellist: FileDto[]single: FileDto,这样在外部就可以根据情况来决定使用哪个。
    2. 然后,对于第3点,我打算对于ElUploadv-model,(称为file-list),仍然保持其UploadFile[]的格式,但上传完成后更新listsingle
    3. 最后,对于第5点,我打算通过<template #default><template #file>两个插槽,替换掉其上传按钮和文件列表样式,从而实现更细粒度的控制。
    4. 其实还有几个大问题,主要集中在回显时,但我在一开始并没有想到。如果想跟随我的思路一块走的话,下面这个“一些深层的问题”可以先不看,在下一节的内容中,随着封装的深入,这些问题将逐渐浮出水面,我也会一一解决。

1.1. 二次封装

References

  1. Upload 上传 | Element Plus
  2. 响应式 API:核心 | Vue.js

上次更新于: