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

这篇具有很好参考价值的文章主要介绍了为摸鱼助力:一份Vue3的生成式ElementPlus表单组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、实现背景

二、简介

三、组织架构设计 

四、实现方式

五、代码示例

六、示例代码效果预览

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

目前项目还有诸多待完善的地方,大家有好的想法、建议、意见等欢迎再次评论,或于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}`
    )
}

六、示例代码效果预览

elementplus 模板,vite、vue3,javascript,开发语言,ecmascript

elementplus 模板,vite、vue3,javascript,开发语言,ecmascript

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

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

项目源码地址:https://github.com/zuotiandeni/lcyBlog文章来源地址https://www.toymoban.com/news/detail-529340.html

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

到了这里,关于为摸鱼助力:一份Vue3的生成式ElementPlus表单组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VUE3结合ElementPlus的过程

    首先在前端项目的依赖列表中加入Elemen的依赖 { “name”: “vue-process”, “version”: “0.0.0”, “private”: true, “scripts”: { “dev”: “vite”, “build”: “vite build”, “preview”: “vite preview”, “lint”: “eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore” }, “dependencies”:

    2024年02月12日
    浏览(39)
  • Vue3+elementplus动态表格table实现

    描述 :使用el-table的时候,根据需求,能够实现由字段个数动态增加表格列,表格行数固定为3行。 实现效果 : 实现代码 : 总结 :如果需要控制行数,并且动态加载列数,故需要两个变量进行设置,这里采用的就是这个思想,能够实现需求效果。

    2024年03月15日
    浏览(63)
  • Vue3+Elementplus+Axios 入门教程详解

    Vue3+Elementplus+Axios 入门教程详解 vue3项目创建 安装第三方框架 vue整合第三方框架 创建登录组件 vue整合axios 1. vue3项目创建 1.1 创建vue3项目,如:vuepro01  备注:vue项目不会创建,请参考 CSDN https://mp.csdn.net/mp_blog/creation/editor/134034891 1.2. 测试项目是否正常启动: 1.2.1 进入项目根

    2024年01月15日
    浏览(56)
  • vue3+vite+ts+elementplus创建项目

    # vue3+vite+ts+pinia 学习笔记 ## 1、创建项目: npm init vite@latest     选择: vue、ts ## 2、进入项目目录后:npm install 安装 ## 3、运行项目: npm run dev ## 4、安装常用插件:     1、安装 npm install vue-router@latest 配置:在src目录下新建router目录,创建index.ts文件代码如下:       ```javascript 创建

    2024年02月09日
    浏览(61)
  • vue3-ElementPlus上传文件【代码】

    上传 下载

    2024年02月10日
    浏览(31)
  • Vue3+Vite+ElementPlus管理系统常见问题

    本文本记录了使用 Vue3+Vite+ElementPlus 从0开始搭建一个前端工程会面临的常见问题,没有技术深度,但全都是解决实际问题的干货,可以当作是问题手册以备后用。本人日常工作偏后端开发,因此,文中的一些前端术语描述可能不严谨,敬请谅解。重点是:这里记录的解决方案

    2024年02月05日
    浏览(54)
  • vue3使用Elementplus 动态显示菜单icon不生效

    菜单icon由后端提供,直接用的字符串返回,前端使用遍历显示,发现icon不会显示 后端提供的是字符串,那么在component :is=\\\"menu.icon\\\"/处读取到的也是字符串,而component组件中要求是一个能渲染的组件,类似如下结构: 想当然的,如果后端直接返回组件形式是不是就可以了。

    2024年02月11日
    浏览(41)
  • 中国省市区地区选择组件(ElementPlus + Vue3 + TS )

    1.引用 2.用法 provinceAndCityData :省市数据(不带“全部”选项) regionData :省市区数据(不带“全部”选项) provinceAndCityDataPlus :省市区数据(带“全部”选项) regionDataPlus :省市区数据(带“全部”选项) CodeToText :例如:CodeToText[‘110000’]输出北京市 TextToCode :例如:

    2023年04月27日
    浏览(68)
  • 怎么在Vue3中正确使用ElementPlus,亲测有效,避坑

    选择自定义项目创建: 选择这几项(空格选择) 后面的几项全部回车,这里就不做介绍了,大胆回车就行,出了事算我的,除非你有特殊需求。(下面是安装成功后的图片) (1) 我这里用的是WebStorm,在命令行中执行下面代码安卓Element-Plus: (2) 在main中配置Element-Plus:

    2024年02月06日
    浏览(136)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包