Vue组件封装方案对比——v-if方式与内置component方式

        近期在准备搭建一个通用组件库,而公司现有的各个系统也已有自己的组件库只是没抽离出来,但是目前有两套不同的组件封装方案,所以对于方案的选择比较困惑,于是对两种方式进行了对比,结合网上找到的一些开源组件库进行分析。记录一下子叭!~

一、现有系统的组件设计思路

        目前,A系统和B系统两个项目中各自有设计自己的组件库,但由于底层封装方案不同,使用时的配置信息也有一些差别,可以通过比较常见的表格、表单组件作为例子直观感受一下。

二、组件封装的方式选择

        每个组件都有其特定的属性(props)、插槽(slots)和事件(events),这些构成了组件的 API。

props子组件接收的参数,最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,还可通过type、validator、required等方式对输入进行验证
slot可以给子组件的特定位置动态插入一些内容或组件(模板)
event子组件可以通知父组件其内部状态的变化或用户的交互行为,使得父组件可以据此更新状态或执行其他操作(子组件在特定的情况下触发事件,父组件监听这些事件并作出响应)

组件封装的方式选择

  • 第一种,先设置好各种类型的组件,使用v-if逐个判断渲染(例子:A系统)
<el-form-item><el-input v-if="item.type == $const.FormCompType.input" /><el-input-number v-if="item.type == $const.FormCompType.number" /><slot v-if="item.type == $const.FormCompType.slot" :item="item" :name="item.slotName" />
</el-form-item>
  • 第二种,利用vue内置的component组件,直接传入Element UI组件(例子:B系统)
<el-form-item><component :is="item.type" />
</el-form-item>

        组件封装在实现表单动态渲染、实现表单可视化配置这方面的应用会比较丰富和直观一些,正好以上A系统中就采用了v-if方法,而B系统则采用了内置component的方法。

        下面,笔者将通过一个表格,从多个角度分析展示两种方案的区别。

v-if方式

component方式

封装繁琐程度

封装代码冗长

需要全面考虑到各种类型

代码简单直接

依靠<component :is="">可以实现任何组件

上手难易

上手简单

需要先学习配置规则

可维护性

因配置结构扁平而更容易定位一些

需要清楚地知道数据结构才能定位

配置方式

层级较少、集中且直观

但只能使用预先设计好的类型、或者更新丰富组件

层级较深、不够直观且容易形成套娃

但可设置的属性更加全面、无需在有新类型时更新组件,只要elementUI有的组件都能直接实现

扩展性

扩展性较好

  • 每次有新的表单控件类型,都必须预先封装、引入并注册才能使用
  • 添加或功能时,只需要在已有的框架内进行扩展,增加相应的判断逻辑和组件即可,不需要修改其他部分的代码

扩展性有限

  • 当需要添加新的表单控件类型或功能时,可能需要修改多处代码,或依赖于ElementUI的更新
  • 对于复杂的表单控件或自定义功能,可能需要重新编写大量代码,难以在现有基础上进行扩展

优势

抽象和重用提供抽象层,代码更清晰可维护,同时提高了组件的重用性

自定义和扩展性:通过type属性可方便地扩展新的控件类型,添加自定义逻辑和样式以满足项目的特定需求

易于管理和维护方便地调整界面结构和行为,需要修改表单控件时,只需修改相应组件,无需在多个地方更改和修改底层的UI组件库组件

灵活性:能够直接利用Element UI提供的丰富组件和特性,无需额外封装,开发效率高

减少封装成本无需投入时间和资源去封装每个表单控件和处理所有可能的边界情况

与库保持同步:UI组件库通常会持续更新和修复问题,直接使用库中的组件可以确保应用始终获得最新的功能和修复,降低了维护成本

快速集成:直接利用现有的 ElementUI 组件,可以快速集成到项目中,减少开发时间

劣势

封装成本高需要投入时间和资源去封装每个表单控件,并确保它们能够正确响应传入的配置

性能损失:可能会导致不必要的渲染和销毁,可能导致一定的性能损失,尤其是在渲染大型表单时。但是这种损失通常是可接受的,可得到优化的

维护性挑战:随着控件类型、数量和复杂度的增加,组件内部逻辑可能会变得复杂,维护起来较为困难

代码冗余:使用 v-if 进行条件渲染可能会导致代码冗余,尤其是在控件类型较多时

配置复杂性:对于复杂的表单或界面,直接传入Element UI组件可能需要更复杂的配置和属性管理,增加了开发的复杂性

缺乏抽象层:代码更依赖于特定的库实现,缺乏抽象层,代码结构可能不够清晰和易于维护

更难以定制封装组件可根据需要添加额外的逻辑或样式来定制组件的行为或外观。对于需要高度定制化的表单控件,直接使用库中的组件可能不够灵活

复用性差:每个表单控件都直接使用ElementUI组件,无法对它们进行统一的封装和扩展

维护成本高:随着组件类型的增加,代码变得难以维护,特别是当需要调整表单控件的样式或行为时,可能需要修改多个地方,维护较为繁琐

其它

  • 上传文件场景下配置依然简洁
  • 可给各组件添加自定义事件
  • 多个表单控件统一样式时,在封装层统一处理就好
  • 可在组件中设计好通用的校验规则
  • 上传文件场景下配置较麻烦
  • 应该如何给el-xxx添加这些事件呢?
  • 多个表单控件统一样式时,需要在JSON配置项里面重复写
  • 校验规则需要在每次使用的时候就写一遍

三、采取折中方式

        方案一和方案二都有各自的优势和不足,所以也许将两者综合一下,设计出第三种方案。

        ①先单独封装好各种类型的表单控件小组件,②再通过<component :is="">来动态渲染,保证高度的组件复用性和扩展性,并避开v-if判断;③对配置的数据结构进行调整使其更扁平化,降低使用门槛并提高开发效率。

        此时,整个组件封装的设计思路 be like:

         用文字描述上图所示的方案:

①在表单Form 上通过<component :is="">来动态渲染不同类型的表单控件小组件,

②对各种类型的控件进行独立封装、分开管理,并导入和注册

③根据需要,在各个小组件中添加一些自定义属性、样式和其他定制化功能等

        优势

▷ 高复用性:通过单独封装各种类型的表单控件小组件,实现了高度的组件复用

▷ 灵活性:通过封装各种表单控件小组件,可以确保每个组件都具备较高的可重用性和可扩展性。同时,使用<component :is="">可以根据配置动态渲染不同的组件,提供了更大的灵活性

▷ 易于维护:每一种特定的表单控件都有独立的封装组件,易于进行单独的维护和测试。每个表单控件都有明确的封装边界(内部实现细节被隐藏起来,只暴露必要的接口供外部使用),这有助于保持代码的模块化和可维护性

▷ 良好的扩展性:添加新的控件类型时,只需要创建新的封装组件并注册到组件库中即可

▷ 数据结构扁平化:通过调整数据结构,使得配置更加扁平、简洁直观和易于管理,更容易理解和操作,降低了使用门槛

        潜在问题

▷ 初期投入大需要投入较多的时间和精力来单独封装各种类型的表单控件小组件

▷ 组件间的耦合度:如果小组件之间的耦合度较高,可能会导致代码难以维护和扩展。因此,在封装组件时需要注意组件的独立性和可重用性

▷ 配置复杂性:虽然通过扁平化数据结构可以简化配置,但如果配置项过多或过于复杂,仍然可能导致配置过程变得繁琐。因此,需要仔细设计配置结构,确保其既简洁又易于理解

需要确保所有可能的组件都已经正确地引用和注册

        优化措施 

♢ 1. 优化配置结构

○ 减少嵌套层级:将原有的嵌套配置结构扁平化,减少层级深度,使配置更加直观。

○ 使用枚举或常量:对于配置中的某些固定值或选项,使用枚举或常量进行替换,避免硬编码和魔法值。

○ 提供默认值:为配置项提供合理的默认值,减少开发者在配置时的必要输入。

♢ 2. 简化组件接口

○ 明确输入输出:每个小组件应该有清晰的输入(props)和输出(events),避免过多的配置选项和复杂的事件处理。

○ 使用统一的接口规范:确保所有小组件都遵循相同的接口规范,这样开发者在使用时就不需要为不同组件学习不同的配置方式

♢ 3. 提高组件复用性

○ 使用插槽(Slots):在小组件中预留插槽,允许开发者自定义内容或扩展功能,提高组件的复用性和灵活性。

○ 提供通用功能:对于一些通用的表单控件功能(如验证、格式化等),可以在小组件中统一实现,减少开发者在每个表单字段上的重复工作。还可以预留一些前缀、后缀等配置。

♢ 4. 优化渲染性能

○ 使用v-show代替v-if:对于频繁切换显示/隐藏的场景,使用v-show可以避免不必要的组件销毁和重建,提高渲染性能。

按需加载:如果项目较大,可以考虑使用代码分割和异步组件技术,按需加载需要的表单控件小组件。

♢ 5. 提供示例和文档

○ 编写清晰的文档:为小组件和配置结构提供详细的文档说明,包括输入输出的参数、用法示例、注意事项等。

○ 提供示例代码:为常见使用场景提供示例代码,帮助开发者快速上手和理解如何使用这些小组件和配置。

♢ 6. 进行单元测试和集成测试

○ 编写单元测试:为每个小组件编写单元测试,确保它们的功能正确性和稳定性

○ 进行集成测试:对整个表单系统的不同配置和组合进行集成测试,确保在各种场景下都能正常工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/756235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抖音店铺规划运营管理计划数据分析工作表

【干货资料持续更新&#xff0c;以防走丢】 抖音店铺规划运营管理计划数据分析表 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 抖音小店运营规划工作表格&#xff08;完整资料包含以下内容&#xff09; 目录 1. 抖店运营管理决策表&#xff1a;该表格用于记…

三维指静脉生物识别成像设备设计和多视图验证研究

文章目录 三维指静脉生物识别成像设备设计和多视图验证研究总结摘要介绍多视角指静脉识别模型结构内容特征编码Transformer(CFET)主导特征选择模块(DFSM) 实验和结果数据集实施细节视角研究池化层的作用消融实验和SOTA方法比较 论文: Study of 3D Finger Vein Biometrics on I…

Linux——进程通信(三)命名管道

前言 我们在之前学习了匿名管道与匿名管道的应用——进程池&#xff0c;但是匿名管道的通信&#xff0c;需要有血缘关系的进程&#xff08;通过fork创建的进程们&#xff09;&#xff0c;如果我想让两个毫不相干的进程进行通信&#xff0c;可以采样命名管道的方式&#xff08;…

Go语言中的锁与管道的运用

目录 1.前言 2.锁解决方案 3.管道解决方案 4.总结 1.前言 在写H5小游戏的时候&#xff0c;由于需要对多个WebSocket连接进行增、删、查的管理和对已经建立连接的WebSocket通过服务端进行游戏数据交换的需求。于是定义了一个全局的map集合进行连接的管理&#xff0c;让所有…

80后深圳设计师原创设计 妙解中小学生午休难题

3月17日至21日&#xff0c;深圳国际智能家居博览会在宝安国际会展中心举办。智慧校园展区成为焦点&#xff0c;吸引了众多目光。智荟康科技展出的午休课桌椅产品&#xff0c;为解决中小学生“趴睡”问题而研发&#xff0c;创新实用&#xff0c;在智慧校园展区中备受好评。 &…

Leetcode 79. 单词搜索

心路历程&#xff1a; 做完这道题才发现是回溯&#xff0c;一开始想的是递归&#xff0c;判断完第i个字符后&#xff0c;只需要挨个判断第i1个字符在不在第i个字符的邻域。后来发现由于不能重复使用元素&#xff0c;所以需要维护一个visited列表&#xff0c;并且在遍历所有可能…

蓝桥杯---代分数

import java.util.Scanner;public class top4 {//全排列分数的那个题目//首先进行n个数的全排列//然后将这n个数字拆分为3个数字&#xff0c;即插入两个板子//然后判断等式是否成立&#xff08;判断条件就是在if里面去进行相关的判断是吗&#xff1f;&#xff1f;&#xff09;s…

Spring项目部署到linux上

目录 一、环境配置 1、数据准备 2、程序配置文件修改 二、打包项目 三、上传jar包到服务器 四、开放端口号 五、运行程序 六、查看日志 七、常见问题 1、服务未启动 2、端口号已被占用 3、端口未开放 一、环境配置 1、数据准备 需要先在linux环境下的数据库中创建…

Go语言之函数、方法、接口

一、函数 函数的基本语法&#xff1a; func 函数名&#xff08;形参列表&#xff09;&#xff08;返回值列表&#xff09; {执行语句...return 返回值列表 } 1.形参列表&#xff1a;表示函数的输入 2.函数中的语句&#xff1a;表示为了实现某一功能的代码块 3.函数可以有返回…

【Linux】进程排队的理解进程状态的表述僵尸进程和孤儿进程的理解

一、进程排队的理解 进程不是一直运行的&#xff0c;进程可能会在等待某种软硬件资源。即使把进程加载到CPU中&#xff0c;也不是一直会运行的。而进程排队&#xff0c;一定是在等待某种软硬件资源&#xff08;可以是CPU&#xff0c;键盘&#xff0c;磁盘&#xff0c;网卡等等设…

rabbitmq-spring-boot-start配置使用手册

rabbitmq-spring-boot-start配置使用手册 文章目录 1.yaml配置如下2.引入pom依赖如下2.1 引入项目resources下libs中的jar包依赖如下2.2引入maven私服依赖如下 3.启动类配置如下4.项目中测试发送消息如下5.项目中消费消息代码示例6.mq管理后台交换机队列创建及路由绑定关系如下…

深入探讨Python中的文件操作与文件IO操作【第141篇—Python实现】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 深入探讨Python中的文件操作与文件IO操作 在Python编程中&#xff0c;文件操作和文件IO操作…

ES集群和分片以及脑裂

文章目录 概要一、概念二、节点角色三、master节点脑裂四、参考 概要 在工作中不可避免会用到ES&#xff0c;而用到ES就不得使用其集群模式了。 单节点的话不得不面临两个重大缺陷&#xff1a;单点故障&#xff08;高可用&#xff09;和海量数据存储搜索。 ES通过集群模式解决…

JSR规范系列(6)——Jakarta EE 9 规范

Jakarta EE 9 规范 Jakarta EE 9 规范 JSR规范系列&#xff08;1&#xff09;——Java版本、JSR规范和JCP社区流程概述 JSR规范系列&#xff08;2&#xff09;——JavaSE规范、JavaEE规范、JSR规范全面整理——截止201908 JSR规范系列&#xff08;3&#xff09;——Java EE 6规…

● 647. 回文子串 ● 516.最长回文子序列 ● 动态规划总结篇

● 647. 回文子串 1.dp数组含义。 之前的题目&#xff0c;差不多都是求什么就怎么定义dp数组&#xff0c;最后返回dp的最后一个元素。但是这里如果定义一维数组dp[i]是[0,i]范围的回文子串的个数的话&#xff0c;怎么根据dp[i-1]得到dp[i]&#xff1f;发现很难找到递归关系…

Linux之gcc_makefile

一、提要 1. 预处理&#xff08;进行宏替换) 2. 编译&#xff08;生成汇编) 3. 汇编&#xff08;生成机器可识别代码&#xff09; 4. 链接&#xff08;生成可执行文件或库文件) 五六十年代&#xff0c;我们编程大多是二进制编程&#xff0c;也就是使用打孔纸带喂给机器 再往后&…

118.Qt入门,实现一个图片查看软件

需要用到的控件 QLabelQLineEditQPushButton 需要实现的功能 打开目录选择图片显示图片的名字显示图片 QLabel基本用法 void setText(const QString &);//设置文本QString text() const;//获取文本void setPixmap(const QPixmap &);设置大小 使用父类QWidget的方法设置…

窗口函数(sample database classicmodels _No.8 )

窗口函数&#xff08;sample database classicmodels _No.8 &#xff09; 准备工作&#xff0c;可以去下载 classicmodels 数据库具体如下 点击&#xff1a;classicmodels 也可以去 下面我的博客资源下载 https://download.csdn.net/download/tomxjc/88685970 文章目录 窗口函…

什么品牌洗地机清洁效果最好?洗地机品牌十大排名:前四名口碑公认

有使用过洗地机的朋友&#xff0c;相信对此都深有感触&#xff0c;洗地机的一洗一吸&#xff0c;清洁效果非常棒&#xff0c;地面的污渍、垃圾、粉尘都坚持不了几秒钟&#xff0c;分分钟可以让家里地面焕然一新&#xff0c;简直不要太香。但是&#xff0c;洗地机那么多&#xf…

Unity类银河恶魔城学习记录11-2 p104 Inventoty源代码

此章节相对较难理解&#xff0c;有时间单独出一章讲一下 Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili InventoryItem.cs…