为摸鱼助力:一份Vue3的生成式ElementPlus表单组件

news2024/11/25 6:58:24

目录

一、实现背景

二、简介

三、组织架构设计 

四、实现方式

五、代码示例

六、示例代码效果预览

七、项目预览地址 & 项目源码地址

目前项目还有诸多待完善的地方,大家有好的想法、建议、意见等欢迎再次评论,或于github提交Issues


一、实现背景

        一切为了摸鱼而努力!!!

        在现代Web应用程序中,表单组件是不可或缺的一部分。但是,手动创建每个表单项是一个非常繁琐的过程。为此,我提供了一个基于Vue3的可配置的表单组件,帮助您快速构建表单,无需手动编写HTML或JavaScript代码。这篇文章将向您展示如何使用JSON配置文件一站式生成Vue3 Form表单组件,并在项目中使用它。

二、简介

        此表单组件是目前内嵌在一个基础项目中的,并没有作单独的npm包进行发布,因为目前是一个比较简单且基础的版本,需要优化的点还非常多。希望大家能多多提出宝贵的意见或建议,本文主要是针对实现思路等进行描述。

        目前实现功能:栅格化布局、监听单个表单数据变化、Form 表单除upload外的所有子组件。

        通过JSON配置一站式生成form表单,该组件保留了ElementPlus全部的使用习惯和使用方式,对ElementPlus原功能进行了完美的保留,支持所有属性设置(方法使用统一事件监听替代)

三、组织架构设计 

        在当前的表单组件中,数据层、UI层、事件层等模块相互独立,通过交互来协调和通信。

        其中,数据层负责存储和管理表单组件的数据;UI层负责渲染表单组件的外观;事件层负责处理用户与表单组件互动时的事件。通过这种方式,我们实现了一个高度可扩展和可重用的表单组件。

四、实现方式

        Vue3支持使用JSX/TSX语法,通过JSX/TSX(我这里使用的是TSX)进行不同表单组件的生成,枚举出Form表单的所有子组件。这里采用TSX的方式可以避免每一种组件都要去写一份Vue文件;

        通过匹配组件类型,生成对应的每一个表单组件;

        为保留ElementPlus组件所有属性,需要采用透传的方式,去列出每一个组件所可能用到的属性显然是不明智的;

        布局排版的生成采用el-row、el-col实现栅格布局,可通过配置进行动态调整;

        ElementPlus表单组件中的所有方法显然不是那么好处理的,因此使用同一个方法去监听每个表单项的变化,并提供给“用户”此时变化的key、newVal以及oldVal,这里采用Proxy进行了数据拦截;

        提供一个表单校验和重置表单数据的方法。

        某些ElementPlus表单组件中会提供一些插槽给用户使用,因此这些插槽也需要保留下来

组件生成示例:

case 'el-input':
    return (
        <ElInput
            type={elItem.specificType}
            {...elItem.bindObj}
            v-model={formData[elItem.key]}
            v-slots={itemInteriorSlotsObject}
        />
    )

五、代码示例

  • 配置项数据
const FormConfig = reactive({
    rowConfigBind: {
        gutter: 20,
        colSpan: 8
        // className: 'row-class'
    },
    formConfigBind: {
        labelPosition: 'top'
    },
    colsList: [
        {
            label: '一个普通的输入框',
            colSpan: 8,
            type: 'el-input',
            specificType: 'text',
            bindObj: {
                placeholder: '请输入文字',
                formatter: (value: any) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
                parser: (value: any) => value.replace(/\$\s?|(,*)/g, '')
            },
            key: 'name'
        },
        {
            label: '一个普通的输入框',
            htmlLabel:
                '<span class="customize-label-style">\n' +
                '            自定义tooltip效果\n' +
                '                <span class="tip-content-wrap">\n' +
                '                      <span class="tip-content">这是自己定义的tooltip</span>\n' +
                '                      <span class="triangle-style"></span>\n' +
                '                </span>\n' +
                '\n' +
                '        </span>\n',
            colSpan: 8,
            type: 'el-input',
            specificType: 'text',
            bindObj: {
                placeholder: '请输入文字',
                formatter: (value: any) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
                parser: (value: any) => value.replace(/\$\s?|(,*)/g, '')
            },
            key: 'name2'
        },
        {
            label: '添加了append文字的输入框',
            colSpan: 8,
            type: 'el-input',
            bindObj: {
                placeholder: '请输入'
            },
            rules: [
                {
                    required: true,
                    message: '请输入',
                    trigger: 'change'
                }
            ],
            slots: [
                {
                    name: 'append',
                    content: '.com'
                }
            ],
            key: 'comAdress'
        },
        {
            label: '添加了append JSX组件的输入框',
            colSpan: 8,
            type: 'el-input',
            bindObj: {
                placeholder: '请输入'
            },
            slots: [
                {
                    name: 'append',
                    content: TestTSXComp
                }
            ],
            key: 'appendJSXComp'
        },
        {
            label: '添加了append Vue组件的输入框',
            colSpan: 8,
            type: 'el-input',
            bindObj: {
                placeholder: '请输入'
            },
            slots: [
                {
                    name: 'append',
                    content: TestVueComp
                }
            ],
            key: 'appendVueComp'
        },
        {
            label: '数字输入框',
            colSpan: 4,
            type: 'el-input-number',
            bindObj: {
                placeholder: '请输入'
            },
            key: 'inputNumberVal'
        },
        {
            label: '测试表单生成函数',
            type: 'slots',
            key: 'content',
            colSpan: 24
        },
        {
            label: '下拉选',
            colSpan: 8,
            type: 'el-select',
            bindObj: {
                placeholder: '请选择',
                multiple: true
            },
            options: [
                {
                    label: '第一个选项',
                    value: 'A',
                    bindObj: {
                        disabled: true
                    }
                },
                {
                    label: '第二个选项',
                    value: 'B'
                },
                {
                    label: '第三个选项',
                    value: 'C'
                }
            ],
            key: 'optionValue'
        },
        {
            label: '单选框',
            colSpan: 8,
            type: 'el-radio',
            options: [
                {
                    label: '第一个选项',
                    value: 'A',
                    bindObj: {
                        disabled: true
                    }
                },
                {
                    label: '第二个选项',
                    value: 'B'
                },
                {
                    label: '第三个选项',
                    value: 'C'
                }
            ],
            key: 'radioValue'
        },
        {
            label: '按钮单选框',
            colSpan: 8,
            type: 'el-radio',
            bindObj: {
                textColor: 'red'
            },
            options: [
                {
                    label: '第一个选项',
                    value: 'A',
                    isButton: true
                },
                {
                    label: '第二个选项',
                    value: 'B',
                    isButton: true
                },
                {
                    label: '第三个选项',
                    value: 'C',
                    isButton: true // 如果是button样式展示,那么设置此属性为true
                }
            ],
            key: 'radioBtnValue'
        },
        {
            label: '自动补全输入框',
            colSpan: 8,
            type: 'el-autocomplete',
            bindObj: {},
            querySearchFun: querySearchFun,
            key: 'autocompleteValue'
        },
        {
            label: '日期选择框',
            colSpan: 8,
            type: 'el-date-picker',
            specificType: 'date',
            bindObj: {},
            key: 'detePickerValue'
        },
        {
            label: '日期时间选择框',
            colSpan: 8,
            type: 'el-date-picker',
            specificType: 'datetime',
            bindObj: {},
            key: 'deteTimePickerValue'
        },
        {
            label: '评分',
            colSpan: 8,
            type: 'el-rate',
            bindObj: {
                voidIcon: 'ChatRound',
                colors: ['#409eff', '#67c23a', '#FF9900'],
                icons: [ChatRound, ChatLineRound, ChatDotRound]
            },
            key: 'rateValue'
        },
        {
            label: '滑块',
            colSpan: 8,
            type: 'el-slider',
            bindObj: {
                showInput: true
            },
            key: 'elSliderValue'
        },
        {
            label: '开关',
            colSpan: 8,
            type: 'el-switch',
            bindObj: {
                style: '--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949'
            },
            key: 'elSwitchValue'
        },
        {
            label: '时间选择器',
            colSpan: 4,
            type: 'el-time-picker',
            key: 'timePickerValue'
        },
        {
            label: '时间选择',
            colSpan: 4,
            type: 'el-time-select',
            key: 'timeSelectValue'
        }
    ]
})
  • 表单数据
// 数据定义
const formData = reactive({
    name: '',
    comAdress: '',
    inputNumberVal: '',
    appendJSXComp: '',
    appendVueComp: '',
    optionValue: [],
    autocompleteValue: ''
})
  • 组件应用
<GenerateElForm
    ref="formInstance"
    :form-config="FormConfig"
    :form-data="formData"
    @updateFormValue="watcherFun"
>
    <template #content>
        <div class="form-slot-one">这是插槽的内容</div>
    </template>
</GenerateElForm>
  •  watcherFun
// 监听数据变化的方法
const watcherFun = (key: string, oldVal: any, newVal: any) => {
    console.log(
        '监听到数据变化',
        `当前变化的key是: ${key}, 它的旧值是: ${oldVal}, 它的新值是: ${newVal}`
    )
}

六、示例代码效果预览

七、项目预览地址 & 项目源码地址

项目预览地址:http://1.14.75.249/

项目源码地址:https://github.com/zuotiandeni/lcyBlog

目前项目还有诸多待完善的地方,大家有好的想法、建议、意见等欢迎再次评论,或于github提交Issues

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

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

相关文章

杭州市等级保护测评机构名录-2023年

等级保护测评机构并不是一成不变的&#xff0c;因为有年审不符合条件被撤销的&#xff0c;也有符合条件新增的&#xff0c;所以需要不定时查看的。这里小编就给大家汇总了2023年杭州市等级保护测评机构名录。 杭州市等级保护测评机构名录-2023年 序号&#xff1a;1 机构名称…

开源SCRM营销平台MarketGo-营销通道

一、概述 互联网逐步由蓝海市场往红海市场走&#xff0c;互联网增量的红利基本到顶了。营销层面过去要获取新用户&#xff0c;现在需要考虑用户的留存、活跃、复购等&#xff0c;重心从拉新向留存用户的精细化运营转移&#xff1b;当人口红利慢慢消失&#xff0c;成本也在逐渐…

零基础学会Python编程——开发环境的搭建

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 学习目标 一.python 介绍 1.Python 的历史 2.Python 的应用领域 二.Pytho…

电源开关这个丨和0哪个在上方?

开关这个丨和0哪个在上方&#xff1f; 开关的I或O的位置&#xff0c;根据安装的方向不同而不同。一般情况下上下方向安装时&#xff0c;都是O在上面。而水平安装时则是左O右I。 开关图片 在这种类型的开关中&#xff0c;是将“|”和“O”作为一个电源开闭循环的标示&#xff0…

PtaPython练习

一、3位水仙花数计算 1、题目 3位水仙花数”是指一个三位整数&#xff0c;其各位数字的3次方和等于该数本身。例如&#xff1a;ABC是一个“3位水仙花数”&#xff0c;则&#xff1a;A的3次方&#xff0b;B的3次方&#xff0b;C的3次方 ABC。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬…

《面试1v1》Spring循环依赖

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Web前端 3D开发入门规划 3D效果将不再是桌面应用的专利

随着 WEB领域的快速发展 3D技术开始不再是桌面应用的专利 WEB3D技术的应用 实现了启用网址的3维呈现 让界面更直观 立体的展示 他打破了传统平面的展示形式 那么 目前的话 政府也有大量的新基建的项目 如 数字孪生 智慧城市 智慧园区 智慧工厂 智慧消费等等项目都涉及到了 3D…

系统磁盘从MBR格式转换成GPT格式来升级win11

之前的《用移动硬盘当系统盘&#xff0c;即插即用》中说到&#xff0c;需要把磁盘格式转化为MBR格式才能执行下去。问题是&#xff0c;win10升级win11要求启动方式为UEFI的话&#xff0c;磁盘格式不能为MBR。其实不升级也不影响啥&#xff0c;但是就是想好看点。所以花了点时间…

推荐系统学习

推荐系统 系统职能&#xff1a;头条/抖音/快手&#xff0c;都是以推荐系统作为流量的分发的主要手段&#xff1b; 职业发展&#xff1a;大数据处理/流式计算/数据挖掘/机器学习/高并发服务等领域。 更具用户的离十信息和行为&#xff0c;向用户推荐他感兴趣的内容 基于行为的…

Modbus TCP 协议详解及C语言示例

Modbus TCP 是一种应用于以太网的通讯协议&#xff0c;基于Modbus RTU协议。Modbus协议是一种应用于串行数据通信的协议&#xff0c;广泛应用于工业控制系统。Modbus TCP 将传统的 Modbus RTU 消息封装在 TCP/IP 报文中&#xff0c;使其能够在现代的以太网环境中进行通信。本文…

VUE 2X MVVM模型 ③

目录 文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持✨ V u e j s Vuejs Vuejs M V V M MVVM MVVM模型Data与El的2种写法总结 文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持✨ ⡖⠒⠒⠒…

【数据分享】1929-2022年全球站点的逐年平均风速(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 对于具体到监测站点的气象数据&#xff0c;之前我们分享过1929-2022年全球气象…

linux-7 awk

目录 1.awk默认规则 2.处理方式 3.格式 4.运算 5.getline 6. 文件内容匹配过滤打印 7.begin . end模式 8.awk条件判断打印 9.awk三元表达 10.awk精准筛选 11.awk数组 1.awk默认规则 当以多空格为分隔符时 自动压缩成一个 默认操作就是打印 默认分隔符时空格 2.处理…

解锁Gradio Interface的便捷与扩展性:load、from_pipeline、integrate和queue方法的魔力

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Day25 实战篇 ——Jmeter实现Java测试实战

Day25 实战篇 ——Jmeter实现Java测试实战 文章目录 Day25 实战篇 ——Jmeter实现Java测试实战一、新建Maven项目二、编写输入参数类、测试类三、编译、打包四、验证开发的函数是否正常1、性能测试过程中,有时候开发想对JAVA代码进行性能测试,Jmeter是支持对Java请求进行性能…

论文解读In-Depth Mouse: Integrating Desktop Mouse into Virtual Reality

In-Depth Mouse: Integrating Desktop Mouse into Virtual Reality HCI2022 honorable ❤️ 将2d的鼠标应用到3d的虚拟空间中&#xff0c;对可选对象进行选择 Challenge 1、如果单纯利用3d虚拟鼠标的3d位置对可选物体进行选择&#xff0c;有可能出现距离更近的物体将虚拟鼠标…

技术讨论:我心中TOP1的编程语言

欢迎关注博主 六月暴雪飞梨花 或加入【六月暴雪飞梨花】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术…

JAVA实现问财爬虫

通过 RestTemplate 将查询语句申请发送至问财&#xff0c;实现同花顺问财的爬虫获取数据&#xff0c;例子中实现了将爬取的数据写入excel文件并染成红色&#xff0c;可将其改造放入数据库中. 通过测试发现爬虫自动能访问一百多次左右&#xff0c;会被官方识别为爬虫&#xff0c…

RocketMQ简介

目录 MQ介绍 MQ的优点和缺点 各种MQ产品的比较 消息发送者步骤分析 消息消费者步骤分析 顺序消息 延时消息 事务消息 1&#xff09;事务消息发送及提交 2&#xff09;事务补偿 3&#xff09;事务消息状态 使用限制 重试队列 重试配置 怎么保证消息消费的时候0丢失…

Java——《面试题——MyBatis篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 目录 前文 1、什么是MyBatis 2、说说MyBatis的优点和缺点 3、#{}和${}的区别是什么&#xff1f; 4、当实体类中的属性名和…