1987WEB视界-分享互联网热点话题和事件

您现在的位置是:首页 > WEB开发 > 正文

WEB开发

二次封装这几个 element-ui 组件后,让代码更加优雅了

1987web2024-03-25WEB开发32
element-ui本身就提供了许多强大的组件。那么为什么还要进行二次封装呢?在日常的开发过程中,部分模块重复性比较强,这个时候就会产生大量重复的代码。这些模块的样式基

element-ui 本身就提供了许多强大的组件。那么为什么还要进行二次封装呢? 在日常的开发过程中,部分模块重复性比较强,这个时候就会产生大量重复的代码。这些模块的样式基本上是比较固定的,而且实现的功能也比较相近。如果每个地方都复制一份相似的代码,既不遵守代码的简洁之道,也不利于后期的维护修改 ... ...

element-ui 因其组件丰富、可拓展性强、文档详细等优点成为 Vue 最火的第三方 UI 框架。element-ui 其本身就针对后台系统设计了很多实用的组件,基本上满足了平时的开发需求。

既然如此,那么我们为什么还要进行二次封装呢?

有以下两种场景

在日常的开发过程中,部分模块重复性比较强,这个时候就会产生大量重复的代码。这些模块的样式基本上是比较固定的,而且实现的功能也比较相近。如果每个地方都复制一份相似的代码,既不遵守代码的简洁之道,也不利于后期的维护修改

此外,在一些业务背景下,产品可能会要求设计新的交互。这个时候也可以基于 element-ui 进行二次开发,将其封装成一个新的组件方便多个地方使用

因为在日常开发过程中,项目主要以 Vue2 为主,并且现在很多公司仍在使用着 Vue2。故本文主要探讨 Vue2 + element-ui 的项目可以怎么封装一些比较通用化的组件

核心思想

主要以父组件传递数据给子组件来实现一些功能,子组件定义固定的展示样式,将具体要实现的业务逻辑抛出来给父组件处理尽量保持 element-ui 组件原有的方法(可以使用 v-bind="$attrs" 和 v-on="$listeners"),如果确实要做更改也尽量让相似的方法方法名不变

组件

InputNumber

el-input-number 是一个很好用的组件,它只允许用户输入数字值。但是这个组件会有个默认值,给他赋予一个null 或""的时候会显示0

这对于有些业务来说并不是很友好,例如添加页面和编辑页面

并且它这个组件的值是居中显示的,和普通的input 框居左显示不同,这就导致了样式不太统一

改造:让 InputNumber 可以居左显示且没有默认值,用法保持和el-input-number组件相似

子组件 InputNumber.vue

id="InputNumber"v-model="insideValue"v-bind="$attrs":controls="controls"v-on="$listeners"/> lang="scss"scoped>#InputNumber {/deep/.el-input__inner{text-align:left;}}

父组件

v-model="value"/>

演示:

OptionPlus

select 组件用在有较多选项时,但是有些选项的长度难免比较长,就会把选项框整个给撑大,例如:

这种还是比较短的时候了,有时因为公司名称较长,或者其他业务要展示的字段过长时就不太友好。

改造:固定选项框的大小,让选项显示更加合理

子组件 OptionPlus.vue

: style="`width: ${width}px`"v-bind="$attrs"v-on="$listeners"> /> lang="scss"scoped>.el-select-dropdown__item{min-height:35px;height:auto;white-space:initial;overflow:hidden;text-overflow:initial;line-height:25px;padding:5px20px;}

父组件

v-model="value"placeholder="请选择"> v-for="item in options":key="item.value":label="item.label":value="item.value":width="200"> lang="scss"scoped>#FormPlus {.ruleForm{width:100%;::v-deep.el-form-item{width:var(--formItemWidth);}::v-deep.el-form-item__content{width:var(--formItemContentWidth);}::v-deep.el-form-item__content.el-date-editor,.el-input{width:var(--formItemContentWidth);}}.btn-container{display:flex;justify-content:flex-end;margin-top:10px;}}

父组件

: list="formList"@submitForm="searchPage"@resetForm="resetForm"/>

演示:

接口获取到的数据可以用this.formList[index] = res.data;来将数据塞进 el-select 的选项数组中

这个组件其实是有一定局限性的,如果确实有特别的需求还是要用 el-form 表单来写

DrawerPlus

抽屉组件可以提供更深一级的操作,往往内容会比较多比较长。因此可以封装一个组件,让操作按钮固定在 drawer 底部,以实现较好的交互

子组件 DrawerPlus.vue

id="drawerPlus"> v-bind="$attrs"v-on="$listeners"> class="scrollbar"> /> class="seat"> class="footer"> name="footer"/> lang="scss"scoped>$height:100px;#drawerPlus {.scrollbar{height:100%;position:relative;.seat{height:$height;}.footer{z-index:9;box-shadow:0-4px6pxrgba(0,0,0,0.08);width:100%;position:absolute;bottom:0px;height:$height;background-color:#fff;display:flex;align-items:center;justify-content:center;}}}

父组件

title="编辑":visible.sync="drawerVisible"direction="rtl"size="45%"> slot="footer"> @ click="drawerVisible = false">取消 type="primary"@click="drawerVisible = false">确定

效果:

使用 el-scrollbar 组件来实现更优雅的滚动效果,底部固定并增加一些阴影增加美观

CopyIcon

在日常开发中,有时可能想实现一键复制,我们可以选择手写复制方法,也可以选择引入 clipboard.js 库帮助快速实现功能

在笔者写过的一篇文章《在网站copy时自带的版权小尾巴以及“复制代码“,可以怎么实现 》,这篇文章中有提到怎么手写复制功能

当然,严格意义上来说,这个组件主要实现不是依赖 element-ui 的,但也有用到其中的一些组件,所以也写在这里

子组件 CopyIcon.vue

: class="`${icon} icon-cursor`"title="点击复制"@click="handleCopy($event, text)"/> lang="scss"scoped>.icon-cursor{cursor:pointer;}

父组件

{{ value }} : text="value"/>

演示:

二次封装虽说方便了后续的开发,但是当封装的组件不能满足需求时,可以考虑迭代或者用回 element-ui 原生的组件

因为笔者水平有限,对组件都是进行比较简单的封装,并且有些地方设计可能不是很合理,还请多多指教~