# 前端如何修改组件库源码来封装符合自己需求的组件?

前端开发的同学们或许会遇到这样的问题:产品中需要实现某项功能,常用的 elementuiantd 等组件库中确实有差不多功能的组件。但实际上这些组件可能并不能满足你的功能,或多或少都需要你去看看如何修改它才能满足你的需求。

比如我曾遇到过 element-ui 中的「树形控件」暴露出的参数没有我需要的(获取参数);或者是「对话框」组件我需要给它的 body 加上上下两条 border 等(样式修改);还有「级联选择器」的多选可搜索功能:需要修改级联看板使它保持展开,且当子节点全部选中时,不展示全部子节点 tag 而只展示它的父节点 tag(源码无此功能)。

例如,我需要的功能是左二(因为我不想选项过多时 tag 占得位置太大),而原组件如左一。我截了两张图对比:

我将这些问题分为以下五类:

  • 样式问题
  • 组件暴露的参数和方法不充分(源码中存在)
  • 可利用部分功能,其余功能要自己开发封装
  • 2+ 个组件之间的联动,多合一
  • 完全没有符合的组件

# 1、组件样式问题

修改单个文件的样式时,以 less 为例,如果你想要修改组件的样式,可以使用 /deep/>>> 来深度选择到你要修改的样式(能够省去一大串的类名)。

.dialog-wrapper {
    /deep/.el-dialog__body{
    	border: solid 1px #999;
    }
}

如果你要修改全局的样式,第一,你可以在全局样式文件中写样式覆盖,引入到 main.js 中即可全局生效。

import "./assets/css/index.css";

第二,跟着组件库提供的『自定义主题』教程修改。

# 2、组件暴露的参数和方法不充分

首先提出一个问题,你怎么知道组件暴露的参数和方法不充分?答案是:因为我看了组件库的源码。

当我们想要获取组件的一个参数,首先是看文档中提供了哪些 AttributesEventsMethods。如果符合需求,直接拿来用就好。如果没有你要的属性和方法,请你先去看看源码中提供了哪些东西没有向外暴露出来的,但是我们能拿来用的。

举个🌰,上述的「Cascader 级联选择器」,我想要在选中一个搜索的选项后不关闭看板。我在组件的 EventsMethods中没有找到相关的方法控制看板展开,如下:

但当我去github上看该组件的源码时,我发现 toggleDropDownVisible() 方法是控制看板展开的。于是我在外部直接调用这个方法就好了。

具体调用方法如下,这样即使方法没有暴露出来,也可以调用它内部的方法:

<el-cascader
    ref="cascader" // ref获取组件
    placeholder="试试搜索:指南"
    :options="options"
    :props="{ multiple: true }"
    filterable></el-cascader
    @visible-change="$refs.cascader.toggleDropDownVisible(true)"> // 调用组件及其方法

# 3、可利用部分功能,其余功能要自己开发封装

第三类其实我们用到的已经比较少了,毕竟现在的组件库已经非常丰富了。但是这一步引起的思考确是很重要的,多看别人的源码有助于提高自己封装组件的水平。

当要用到一个组件,但从头开发这个组件既复杂又耗时,而组件库中这个组件需要再往上加一些功能就能为你所用时,你可以考虑把组件库的代码拿到自己本地,修改它。

第一步你需要将组件代码浏览一遍,了解它的逻辑。看看你需要加什么代码,如果在vue中,使用 computedwatch,或是修改 createdmountedmethods就能完成你的功能,那么就大胆地尝试。

# 4、2+ 个组件之间的联动,多合一

到这一步,其实你已经翻越最难的大山了!而这里要说的多个组件之间的联动其实已经处于优化用户体验的道路上了。思考一下,什么时候会用到多个组件之间的联动呢?

「Form 表单」、「Table 表格」和「Pagination 分页」

# 5、完全没有符合的组件

如果你要的组件,外部的组件库中都没有提供,那就自己动手封装一个。尽可能将你的组件变得通用,兼容。尝试想一想你的组件是否在其他情况下也能用。另外也可以多看看别人是如何封装组件的,这有助于你自己开发。

如果你可以将你在前端开发道路上自己封装的组件一个个收集起来,大概率可以方便你以后相同场景下直接复用,也有助于你的代码解耦。

Vue Demo Collection (opens new window) 是我在开发过程中遇到的通用 Vue 组件的 demo 收集,包含了 Vue/CSS/Echarts 等一些可以复用的组件 ❤️,基本上我认为可以复用的组件和代码片段我都会记录在这,方便自己的回顾和使用,也算是个人成长的记录。

上次更新: 1/21/2022, 5:24:06 PM