基于element封装自定义组件的那些事

element-ui是一款好用的基于vue的一个UI框架,得益于此类UI框架和组件的出现,使得我们前端开发人员在工作过程中能够拿来即用,减少了造轮子的时间,(主要是减少加班时间),但在此基础上,有些小伙伴为了能更加减少加班时间,往往会选择,在基于UI框架基础上,封装一些自定义的组件,将一些常用的设置、方法包含进去,从而减少代码量和重复的复制粘贴操作。基于此,本文想谈一下,在基于element-ui封装自定义组件的时候,有哪些技巧可以使用。

梳理逻辑

当我们想要做一个新的东西的时候,我们无非是从”做什么“、”怎么做“,”如何做“这些基础的问题出发的,封装组件也不例外。

1. 做什么

个人认为,当我们想要去封装一个新的组件,尤其是在已有的轮子上面进行优化封装的时候,一定是因为想抛弃或者优化某些繁琐的操作,或者原有组件的基础功能不能满足一些高阶功能,那么这些操作,就是封装组件时候要做的内容。

el-table组件为例,在使用的时候,要根据数据的组成和需要展示的内容,分别写出一个个的el-table-column来展示每列数据,这种操作繁琐且代码行数冗余,当在另外一个场景中同样用到el-table组件时,常常是把el-table-column列复制过去进行参数的修改,或者重新写el-table-column,无论是哪种操作,都会增加我们书写代码的繁琐度,那么在封装组件时,就可以把减少el-table-column或者取消el-table-column的书写作为一项切入点,由此,我们就识别到了要封装的组件的一个需求点,同样的方式,识别出组件的其他需求点,那么”组件要做哪些东西“这个问题就得到了解决。

2. 怎么做

在第一步识别出组件的需求之后,下一步就要根据一个一个的需求点进行方案的设计,也就是怎么去实现需求的问题,针对上文的例子,要减少用户el-table-column或者取消el-table-column的书写,那就需要将el-table-column的书写和渲染逻辑放到组件内部实现,很自然地,我们想到可以通过传参的形式,将列数据以json串的形式传入组件内部,组件内部通过for循环的方式遍历数据并生成对应的el-table-column列,至此就完成了这个需求点的基本功能。

// todo
放图

在此基础上,我们不禁要思考,在渲染表格数据的时候,有时候不仅仅单纯地展示数据,而是要进行一个额外的处理,比如说在数据前面加上图标,那么这时,刚刚的处理方式就不能满足这个需求了,element的官网给出的示例是通过插槽来使得用户可以自定义列模板,那么我们在封装组件的时候就可以参照此做法,也预留出插槽使得用户能够自定义想要的列模板。

image.png

这只是标识出的一个简单的场景一,在封装组件的时候,根据一个需求点,结合一些具体的业务需求,尽可能多的识别出其他的场景二、场景三,……然后不断地去完善这个需求点。

3. 如何做

前两步可以说是需求收集和方案设计阶段,那么到了这一阶段,就是要进行实际编码的阶段了,在这个过程中,我们更多的是要考虑技术层面的问题,也就是通过具体的代码去实现上面的方案设计。下面记录的是在编写组件过程中关于传参的一些设计和技巧。

设计传参

  1. $attrs$listeners

在实操组件过程中,对于固定的操作,以及无需用户关心的操作,通常是直接写个固定值在组件内部,而那些需要用户自定义的操作则采用父子通信的传参方式,通过prop方式接受外部传参,通常如果用户不传时,组件会设置一个默认值以达到组件的默认效果。然而,我们不得不考虑的一个问题是,el-table自身有很多入参,实现的效果也很多样,如果我们只期望封装出来的组件只具备el-table一部分功能的时候,可以只将这部分功能涉及到的参数以prop方式传入,但是如果想在封装一部分功能的基础上保留el-table组件的其他功能,那么这时,如果再一个一个地将参数以prop参数传入,整个组件的prop就会变得异常庞大,无用代码量也会增多。这时,不妨考虑一下使用v-bind="$attrs"v-on="$listeners"

以下是来自vue官网的关于$attrs$listeners的介绍:

$attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

可见,v-bind="$attrs"v-on="$listeners"是我们在原有组件基础上进行高阶组件封装的一个很好的利器,用户将一些el-table的参数和方法传入到我们封装的组件内部,封装的组件不对这些参数和方法作额外的处理,而直接将这些内容继续传入到el-table内部,el-table再对这些参数和方法作出具体的反应,不难看出,我们封装的自定义组件在这个过程中只充当了一个中间件的作用,用来接收外部参数并转发给el-table,从而能保留el-table的这些自身操作。

最后总结,在封装组件时,对于组件所封装和关注的部分的传参以prop形式传入组件内容,而组件不关注或者不封装的部分,可以通过设置v-bind="$attrs"v-on="$listeners"是保留element-ui组件的自身功能。

  1. .sync

如果将组件称为子组件,调用组件的部分称为父组件的话,那么父组件通过prop方式将参数传入到组件内部,组件通过$emit方式将方法暴露给父组件,或者通过ref对子组件做标记,父组件可以通过vm.$refs.[子组件的ref].[子组件的属性/方法]这种方式直接取得子组件的数据,这也是一般父子组件进行通信的方式,但是从子组件向父组件传递数据时,父子组件中的数据仍不是每时每刻都同步的,但在某些特殊的需求场景下,我们可能会希望父子组件中的数据时刻保持同步,以el-pagination组件为例,current-pagepage从外部传入,当切换页码和改变每页数量时,我们期望外部传入的current-pagepage能同步更新,此时,.sync就派上了用场。官网关于 .sync的介绍

发布组件

组件封装完成之后,可以通过发布到npm仓库的方式供其他人使用,发布npm包的方式大家可自行百度。在发布npm包的时候,还需要注意的两个点是:版本号和文档。版本号的命名和更新是极其重要的,不能忽略,在后续的发布和维护时,也要注意版本号的设置,不能随意修改。对于文档,可以说是组件的门面,用户一般都是通过文档来使用组件的,文档的书写与否和文档的详细程度能直接影响到用户对组件的使用率和评价。好的文档也能增加开发者的底气,比如说,如果有人吐槽你的组件没有某个功能不好用,而实际上组件是有这个功能并且文档中已经详细介绍这个功能的时候,你就可以优雅地这样回复他。

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容