位置: IT常识 - 正文

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

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

推荐整理分享二次封装这几个 element-ui 组件后,让代码更加优雅了(接口二次封装),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:二次封装element,二次封装什么意思,gho二次封装,二次封装element,二次封装业务组件原则,二次封装组件,二次封装什么意思,二次封装组件,内容如对您有帮助,希望把文章链接给更多的朋友!

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

<template> <el-input-number id="InputNumber" v-model="insideValue" v-bind="$attrs" :controls="controls" v-on="$listeners" /></template><script>export default { // 让父组件 v-model 传参 model: { prop: 'numberValue', event: 'change', }, props: { numberValue: { type: [Number, String], default: undefined, }, // 默认不显示控制按钮,这个可以根据实际情况做调整 controls: { type: Boolean, default: false, }, }, data () { return { insideValue: undefined, }; }, watch: { numberValue (newVlalue) { // 若传入一个数字就显示。为空则不显示 if (typeof newVlalue === 'number') { this.insideValue = newVlalue; } else this.insideValue = undefined; }, },};</script><style lang="scss" scoped>#InputNumber { /deep/ .el-input__inner { text-align: left; }}</style>

父组件

<template> <InputNumber v-model="value" /></template><script>import InputNumber from './InputNumber';export default { components: { InputNumber, }, data () { return { value: null, }; },};</script>

演示:

OptionPlus

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

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

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

子组件 OptionPlus.vue

<template> <el-option :style="`width: ${width}px`" v-bind="$attrs" v-on="$listeners"> <slot /> </el-option></template><script>export default { props: { width: { type: Number, }, },};</script><style lang="scss" scoped>.el-select-dropdown__item { min-height: 35px; height: auto; white-space: initial; overflow: hidden; text-overflow: initial; line-height: 25px; padding: 5px 20px;}</style>

父组件

<template> <el-select v-model="value" placeholder="请选择"> <OptionPlus v-for="item in options" :key="item.value" :label="item.label" :value="item.value" :width="200"> </OptionPlus> </el-select></template><script>import OptionPlus from './OptionPlus';export default { components: { OptionPlus, }, data () { return { value: null, options: [{ value: '选项1', label: '黄金糕', }, { value: '选项2', label: '双皮奶特别好吃,以顺德的最出名,推荐尝试', }, { value: '选项3', label: '蚵仔煎', }, { value: '选项4', label: '龙须面', }, { value: '选项5', label: '北京烤鸭', }], }; },};二次封装这几个 element-ui 组件后,让代码更加优雅了(接口二次封装)

效果:

FormPlus

后台系统肯定会有查找功能,搜索条件大部分都是这三种,输入框、下拉框和日期选择。所以可以整合这三个常用的元素,将它们封装成一个易于使用的组件

这三个组件是用来过滤条件的,因此一般与查询和重置按钮在一起

子组件FormPlus.vue

<template> <div id="FormPlus"> <el-form ref="ruleForm" :rules="rules" :inline="inline" :model="ruleForm" class="ruleForm" :label-width="labelWidth" :style="formStyle"> <template v-for="(item, index) in list"> <template v-if="!item.type || item.type === 'input'"> <el-form-item :key="index" :label="item.label" :prop="item.model" :required="item.required"> <el-input v-model.trim="ruleForm[item.model]" :clearable="item.clearable === undefined || item.clearable" filterable :placeholder="item.placeholder" /> </el-form-item> </template> <template v-if="item.type === 'select'"> <el-form-item :key="index" :label="item.label" :prop="item.model" :required="item.required"> <el-select :style="`width: ${formItemContentWidth}`" v-model.trim="ruleForm[item.model]" :clearable="item.clearable === undefined || item.clearable" filterable :placeholder="item.placeholder || ''"> <!-- 使用上文提到的 OptionPlus 组件 --> <OptionPlus v-for="(i, key) in item.options" :key="i[item.optionsKey] || key" :label="i[item.optionsLabel] || i.label" :value="i[item.optionsValue] || i.value" :width="formItemContentWidth" /> </el-select> </el-form-item> </template> <template v-if="item.type === 'date-picker'"> <el-form-item :key="index" :prop="item.model" :label="item.label" :required="item.required"> <el-date-picker v-model.trim="ruleForm[item.model]" :clearable="item.clearable === undefined || item.clearable" :type="item.pickerType" :placeholder="item.placeholder" :format="item.format" :value-format="item.valueFormat" :picker-options="item.pickerOptions" /> </el-form-item> </template> </template> <slot /> </el-form> <el-row> <el-col class="btn-container"> <el-button class="el-icon-search" type="primary" @click="submitForm">查询</el-button> <el-button class="el-icon-refresh" @click="resetForm">重置</el-button> </el-col> </el-row> </div></template><script>import OptionPlus from './OptionPlus';export default { components: { OptionPlus }, props: { list: { type: Array, default: () => [], }, inline: { type: Boolean, default: true, }, labelWidth: { type: String, default: '100px', }, formItemWidth: { type: String, default: '400px', }, formItemContentWidth: { type: String, default: '250px', }, rules: { type: Object, default: () => { }, }, }, data () { return { ruleForm: {}, }; }, computed: { formStyle () { return { '--formItemWidth': this.formItemWidth, '--formItemContentWidth': this.formItemContentWidth, }; }, }, watch: { list: { handler (list) { this.handleList(list); }, immediate: true, deep: true, }, }, methods: { // 所填写数据 submitForm () { this.$refs['ruleForm'].validate((valid) => { if (valid) { const exportData = { ...this.ruleForm }; this.$emit('submitForm', exportData); } else { return false; } }); }, // 默认清空所填写数据 resetForm () { this.$refs.ruleForm.resetFields(); this.handleList(this.list); this.$emit('resetForm'); }, handleList (list) { for (let i = 0; i < list.length; i++) { const formitem = list[i]; const { model } = formitem; this.$set(this.ruleForm, model, ''); } }, },};</script><style 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; }}</style>

父组件

<template> <FormPlus :list="formList" @submitForm="searchPage" @resetForm="resetForm" /></template><script>import FormPlus from './FormPlus';export default { components: { FormPlus, }, data () { return { formList: [ { label: '编号', model: 'applyNumber', placeholder: '请输入编号' }, { label: '名称', model: 'name', placeholder: '请输入名称' }, { type: 'date-picker', label: '开始时间', model: 'startTime', valueFormat: 'yyyy-MM-dd HH:mm:ss', placeholder: '请选择开始时间' }, { type: 'select', label: '状态', model: 'status', placeholder: '请选择状态', options: [] }, ], }; }, methods: { // 可以取到子组件传递过来的数据 searchPage (ruleForm) { console.log(ruleForm, 'ruleForm'); }, resetForm () { }, },};</script>

演示:

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

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

DrawerPlus

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

子组件 DrawerPlus.vue

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

父组件

<template> <DrawerPlus title="编辑" :visible.sync="drawerVisible" direction="rtl" size="45%"> <template slot="footer"> <el-button @click="drawerVisible = false">取消</el-button> <el-button type="primary" @click="drawerVisible = false">确定</el-button> </template> </DrawerPlus></template><script>import DrawerPlus from './DrawerPlus';export default { components: { DrawerPlus, }, data () { return { drawerVisible: false, }; },};</script>

效果:

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

CopyIcon

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

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

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

子组件 CopyIcon.vue

<template> <i :class="`${icon} icon-cursor`" title="点击复制" @click="handleCopy($event, text)" /></template><script>// 引入 clipboard.jsimport Clipboard from 'clipboard';export default { props: { // 接收复制的内容 text: { type: [String, Number], default: null, }, // 默认是复制 icon,可自定义 icon icon: { type: [String], default: 'el-icon-copy-document', }, // 自定义成功提示 message: { type: [String, Number], default: null, }, }, methods: { handleCopy (e, _text, message) { const clipboard = new Clipboard(e.target, { text: () => _text }); const messageText = message || `复制成功:${_text}`; clipboard.on('success', () => { this.$message({ type: 'success', message: messageText }); clipboard.off('error'); clipboard.off('success'); clipboard.destroy(); }); clipboard.on('error', () => { this.$message({ type: 'warning', message: '复制失败,请手动复制' }); clipboard.off('error'); clipboard.off('success'); clipboard.destroy(); }); clipboard.onClick(e); }, },};</script><style lang="scss" scoped>.icon-cursor { cursor: pointer;}</style>

父组件

<template><div> <span>{{ value }}</span> <CopyIcon :text="value" /></div></template><script>import CopyIcon from './CopyIcon';export default { components: { CopyIcon, }, data () { return { value: '这里来测试一下-初见雨夜', }; },};</script>

演示:

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

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

本文链接地址:https://www.jiuchutong.com/zhishi/303731.html 转载请保留说明!

上一篇:input输入框限制只能输入数字的方法实例(个人认为最好的)(input输入框限制最大字数)

下一篇:Python中pdb设置断点(python设置断点)

  • excel怎么在方框里打√符号(excel怎么在方框里打对号)

    excel怎么在方框里打√符号(excel怎么在方框里打对号)

  • 微信不领红包怎么知道多少钱(微信不领红包怎么看发了多少钱)

    微信不领红包怎么知道多少钱(微信不领红包怎么看发了多少钱)

  • 小米手环4有什么颜色(小米手环4有什么功能作用)

    小米手环4有什么颜色(小米手环4有什么功能作用)

  • 华为ELSAN00是什么手机(华为elsan00是什么型号多少钱)

    华为ELSAN00是什么手机(华为elsan00是什么型号多少钱)

  • 流量可以打开WiFi打不开(流量可以打开的网站wifi无法连接)

    流量可以打开WiFi打不开(流量可以打开的网站wifi无法连接)

  • 智行火车票学生票为什么还是原价(智行火车票学生认证不了)

    智行火车票学生票为什么还是原价(智行火车票学生认证不了)

  • 主板和cpu是一起的吗(电脑主板和cpu是在一起的吗)

    主板和cpu是一起的吗(电脑主板和cpu是在一起的吗)

  • hands free和stereo的区别(handsfree和stereo切换)

    hands free和stereo的区别(handsfree和stereo切换)

  • 数据透视表字段名无效什么意思(数据透视表字段名无效怎么解决)

    数据透视表字段名无效什么意思(数据透视表字段名无效怎么解决)

  • 显示屏没信号什么原因(显示屏显示无信号就不亮了)

    显示屏没信号什么原因(显示屏显示无信号就不亮了)

  • 小米5可以单独换外屏吗(小米5可以双卡双待吗)

    小米5可以单独换外屏吗(小米5可以双卡双待吗)

  • 探探能搜索好友吗(探探可以搜索人么)

    探探能搜索好友吗(探探可以搜索人么)

  • 如何取消天猫会员店(如何取消天猫会员)

    如何取消天猫会员店(如何取消天猫会员)

  • airport怎么改名(怎么改名airpods)

    airport怎么改名(怎么改名airpods)

  • 荣耀20pro解锁方式(荣耀20pro解锁方式有哪些)

    荣耀20pro解锁方式(荣耀20pro解锁方式有哪些)

  • 抖音怎么查看撤回的消息(抖音如何查看撤回的消息)

    抖音怎么查看撤回的消息(抖音如何查看撤回的消息)

  • vivoy93的返回键在哪里(vivoy93s返回键怎么调成按键)

    vivoy93的返回键在哪里(vivoy93s返回键怎么调成按键)

  • iphone如何开热点(iphone怎么开热点给电脑)

    iphone如何开热点(iphone怎么开热点给电脑)

  • 微信收款码名字怎么更改(微信收款码名字大全)

    微信收款码名字怎么更改(微信收款码名字大全)

  • 滴滴行程单真假验证(滴滴行程单真伪查询)

    滴滴行程单真假验证(滴滴行程单真伪查询)

  • 想用U盘装系统索尼笔记本如何进Bios设置U盘启动(想用u盘装系统怎么弄)

    想用U盘装系统索尼笔记本如何进Bios设置U盘启动(想用u盘装系统怎么弄)

  • bigfix.exe是什么文件的进程 bigfix进程安全吗(bigfile是什么意思)

    bigfix.exe是什么文件的进程 bigfix进程安全吗(bigfile是什么意思)

  • 讲讲vue3下会造成响应式丢失的情况

    讲讲vue3下会造成响应式丢失的情况

  • 二手房交易税费2023新规定
  • 运输行业一般纳税人税率
  • 工资申报是当月申报当月的吗
  • 支票上的法人章和财务章是央行盖吗
  • 理财收益交增值税
  • 进项都抵扣完了怎么办
  • 高新企业收到政府补贴会计分录
  • 转出未交增值税是借方还是贷方
  • 按月按季申报
  • 固定资产出售损益
  • 核定征收企业股权转让所得税
  • 普通发票与增值税发票的图片
  • 新企业会计准则什么时候实施的
  • 应付账款不付处理分录如何写?
  • 小规模纳税人附加税税率各是多少
  • 工程项目分包需要缴纳企业所得税吗
  • 营改增后还有建筑业发票吗
  • 增值税发票不小心撕坏了怎么办
  • 建筑业外出经营管理办法
  • 商品销售税金及附加科目现在改了吗
  • 营改增后固定资产入账
  • 当年亏损可以用以前年度来弥补吗
  • 股权转让需要什么资料
  • 发票认证后还要做什么
  • 计提固定资产会计科目
  • 收到转账支票怎么填写凭证
  • 重装系统最好排名
  • mac如何修改
  • 转出未交增值税会计科目
  • PHP:oci_fetch_object()的用法_Oracle函数
  • 国税打印发票
  • 代扣费用会计分录
  • docker管理系统
  • 确认收入与结转成本会计分录怎么写
  • 印花税计税基础含增值税
  • 建筑劳务公司适应什么工程
  • 销售返利账务处理及注意事项
  • 固定资产清理的金额怎么算
  • 印花税都有什么类目
  • sql2016异地备份
  • 利润减负债
  • 固定资产报废能否继续使用
  • 双定户经营所得税税率
  • 一般纳税人增值税申报表怎么填写
  • 红字发票账务处理需冲回成本吗?
  • 出纳去银行存现
  • 产品研发专利
  • 转卖增值税犯罪吗
  • 享受研发费用加计扣除需要什么条件
  • 企业工资薪金支出怎么确认
  • 场地租用招标方案怎么写
  • 如何查询公司经营异常
  • 企业建账涉及哪些内容
  • win8系统安装软件在桌面找不到
  • 系统备份恢复系统
  • xp快捷桌面图标
  • xp系统文件夹选项在哪
  • Ubuntu 14.04系统怎么安装Nvidia 私有显卡驱动?
  • explore.exe进程的作用
  • ubuntu装eclipse
  • 无人值守工厂
  • WIN764位系统8G内存识别一半解决办法
  • linux终端有哪些
  • msstat.exe - msstat是什么进程 有什么用
  • powerdvd remote下载
  • win8系统自带应用都打不开了怎么办
  • win10系统组策略怎么打开
  • windows 10 mobile--移动版
  • win7无法更改工作组
  • js取二维数组数组的值
  • node.js上传文件
  • javascript 作用
  • js检测类型的方法
  • 综治维稳中心是干啥的啊
  • 日本的消费税是累进税吗
  • 国税发票打印汇总怎么弄
  • 烟叶税属于中央税还是地方税
  • 东风小康和重庆金康
  • 外贸公司销售额可以10亿以上吗
  • 注销的卡补回来还能恢复以前的套餐吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设