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.rhkb.cn/news/279328.html

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

相关文章

Android 源码中 内置系统App(整个APP源码方式集成)

1. 如何新建一个系统 App 项目 使用 Android Studio 新建一个空项目 FirstSystemApp&#xff0c;包名设置为 com.yuandaima.firstsystemapp&#xff0c;语言选择 Java。后面为叙述方便称该项目为 as 项目。 接着在 jelly/rice14 目录下创建如下的目录和文件&#xff1a; 接着…

Angular进阶之八: Angular Animation在项目中的实践经验

使用 Angular 进行项目开发的程序员应该都很熟悉 Angular Animation。这是一个 Angular 原生的动画库&#xff0c;它可以替代或者辅助完成原本需要使用 css 的动画功能。 Angular 在国内的运用是很有限的&#xff0c;可借鉴的文档并不很丰富。尤其对于 Angular 动画模块的应用…

Tensorflow2.0笔记 - Himmelblau函数优化案例

本笔记记录Himmelblau函数优化案例代码&#xff0c;包括函数的图形绘制和梯度下降求解局部最优解的过程。 import tensorflow as tf import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib import pyplot as plt tf.__version__#Himmelblau函数 #https…

Java 学习和实践笔记(41):API 文档以及String类的常用方法

JDK 8用到的全部类的文档在这里下载&#xff1a; Java Development Kit 8 文档 | Oracle 中国

Http 超文本传输协议基本概念学习摘录

目录 HTTP协议 超文本传输协议 HyperText超文本 HTML超文本标记语言 HTTP协议原理 请求发送 服务器处理 响应发送 连接关闭或保持 HTTP协议版本 HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3 HTTP请求方法 GET POST PUT DELETE HEAD OPTIONS HTTP请求头字…

Flutter开发多端天气预报App:一场奇妙的编程之旅

在这个信息爆炸的时代&#xff0c;我们渴望获取最新的天气信息&#xff0c;以便更好地规划我们的生活。而作为程序员的我们&#xff0c;又怎能错过用技术手段打造一款个性化、便捷的天气预报App呢&#xff1f;在本篇博客中&#xff0c;我将带你踏上一场奇妙的编程之旅&#xff…

MacOS Xcode 使用LLDB调试Qt的 QString

环境&#xff1a; MacOS&#xff1a; 14.3Xcode&#xff1a; Version 15.0Qt&#xff1a;Qt 6.5.3 前言 Xcode 中显示 预览 QString 特别不方便, 而Qt官方的 lldb 脚本debugger/lldbbridge.py一直加载失败&#xff0c;其他第三方的脚本都 不兼容当前的 环境。所以自己研究写…

31-Java前端控制器模式(Front Controller Pattern)

Java前端控制器模式 实现范例 前端控制器模式&#xff08;Front Controller Pattern&#xff09;是用来提供一个集中的请求处理机制&#xff0c;所有的请求都将由一个单一的处理程序处理该处理程序可以做认证/授权/记录日志&#xff0c;或者跟踪请求&#xff0c;然后把请求传给…

内存泄漏检测、单向链表的操作

我要成为嵌入式高手之3月19日数据结构第二天&#xff01;&#xff01; ———————————————————————————— valgrind内存测试工具 让虚拟机上网、在虚拟机上下载软件&#xff0c;参考笔记&#xff1a; 我要成为嵌入式高手之2月3日Linux高编第一天&am…

线程和进程的区别和联系

一、什么是进程 进程(Process), 是一个具有独立功能的程序关于某个数据集合的一次运行活动&#xff0c;是系统进行 【资源分配和调度】 的一个独立单位。 进程是【程序】的【一次执行】(是计算机中程序的执行过程&#xff0c;而不是计算机中的程序)进程是系统进行【资源分配和…

第二证券策略:股指预计维持震荡格局 关注汽车、半导体等板块

第二证券指出&#xff0c;方针组合拳齐下&#xff0c;商场蓄势待起&#xff0c;短期指数或向上挑战3100点&#xff0c;低位业绩板块、叠加AI或是3月商场主要出资主线&#xff0c;尽管商场情绪高涨&#xff0c;但不主张情绪化追涨&#xff0c;究竟上方还有压制&#xff0c;放量打…

[BSidesCF 2019]Pick Tac Toe

[BSidesCF 2019]Pick Tac Toe 首先进行常规的信息收集&#xff0c;尝试几次下三子棋后查看源码发现 此时只需要更改id为r的&#xff0c;将他改为X&#xff0c;我们就胜利了抓包发现&#xff0c;数据通过post提交参数为move&#xff0c;顺便再下一子&#xff0c;抓包更改为move…

奥特曼剧透GPT-5,将在高级推理功能上实现重大进步

奥特曼&#xff1a;“GPT-5的能力提升幅度将超乎人们的想象...” 自 Claude 3 发布以来&#xff0c;外界对 GPT-5 的期待越来越强。毕竟Claude 3已经全面超越了 GPT-4&#xff0c;成为迄今为止最强大模型。 而且距离 GPT-4 发布已经过去了整整一年时间&#xff0c;2023年3月1…

长安链Docker Java智能合约引擎的架构、应用与规划

#功能发布 长安链3.0正式版发布了多个重点功能&#xff0c;包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。 在《2022年度长安链开源社区开发者调研报告》中&#xff0c;对Java合约语言支持是开…

9.用FFmpeg测试H.264文件的解码时间

1. Essence of Method 要测试对H.264文件的解码时间&#xff0c;可以使用FFmpeg进行操作。FFmpeg是一个开源的多媒体处理工具&#xff0c;可以用来处理视频和音频文件&#xff0c;包括解码H.264文件。以下是使用FFmpeg的命令行来测试解码时间的方法&#xff1a; ffmpeg -i in…

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

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

React的生命周期

生命周期图谱: React lifecycle methods diagram 生命周期三大阶段 挂载阶段 流程: constructor > render > componentDidMount 触发: ReactDOM.render(): 渲染组件元素 更新阶段 流程: render > componentDidUpdate 触发: setState() , forceUpdate(), 组件接收到新…

JS+CSS3点击粒子烟花动画js特效

JSCSS3点击粒子烟花动画js特效 JSCSS3点击粒子烟花动画js特效

【python】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

文章目录 一、遇到的问题&#xff1a;jupyter notebook网页不自动跳出&#xff08;一&#xff09;输入jupyter notebook命令&#xff08;二&#xff09;手动打开网页 二、解决办法&#xff1a;指定浏览器&#xff08;一&#xff09;找文件 jupyter_notebook_config.py&#xff…

JVM常用垃圾收集器

JVM 4.1 哪些对象可以作为GC ROOT? 虚拟机栈&#xff08;栈帧中的局部变量表&#xff09;中引用的对象本地方法栈中引用的对象方法区静态变量引用的对象方法区常量引用的对象被同步锁持有的对象JNI&#xff08;Java Native Interface&#xff09;引用的对象 4.2 常用垃圾收集…