iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue2ElementSchemaForm配置式生成表单的实现
  • 657
分享到

Vue2ElementSchemaForm配置式生成表单的实现

2024-04-02 19:04:59 657人浏览 薄情痞子
摘要

目录前置知识点Component$attrs$listeners表单的结构是什么样的配置数组数据结构结语前置知识点 为了实现一个Schema FORM配置式表单的生成,需要了解一部分

前置知识点

为了实现一个Schema FORM配置式表单的生成,需要了解一部分前置知识点。

Component

Vue 提供了一个内置组件 Component,用来动态渲染组件,举个例子,本篇文章以Element UI 为例,假设我们全局注册了Element UI的组件,那么下面一段代码

<Component is="el-input"></Component>

将被渲染为el-input组件。

好了,最重要的实现知识点已经完了,只要了解了这一点,我这个Schema Form的实现思路,你就能完全看懂了,就这么简单。

但是为了我们表单的易用性,我们再了解一点儿其他的。

比如Component组件并非只能接收一个字符串,渲染全局组件,同时可以接收一个Component组件,也就是说,当我们Element UI 组件没有全局注册的时候,我们可以通过import { ElInput } from 'element',传递给Component组件,同样可以完成渲染一个el-input组件的功能。

$attrs

第二个知识点,vue属性透传,假如你有这么一个疑惑 —— 我对el-input进行了二次封装,那el-input接收的props我是否需要在二次封装的组件中进行props的定义,再逐一传递给el-input才能生效。

如果有这样的疑惑那么$attrs可以帮你,对于二次封装的组件,通过定义v-bind="$attrs",传递给父组件的属性即可透传给el-input,于是就有了这么一个疑问,$attrs可以绑定给v-bind,那么一个普通的对象可以吗,答案是可以的。

这是我们 schema form 变得好用的第二个重要的知识点。

$listeners

$attrs 相同,做事件透传的,通过v-on绑定。

以上就是我认为,实现Schema Form配置式生成表单所需要掌握的全部知识及扩展思考,接下来,我们简单完成一个配置式表单.

表单的结构是什么样的

1、我可能希望对表单进行一部分特殊的处理,所以,包一层div总是没错的,当然,这是我的习惯,你们可以自行选择。

2、既然是表单,那一定被el-form包裹。

3、为了配置式布局的需要,我希望引入el-row el-col栅格系统

4、无论如何完善表单,必然不可能满足所有要求,那最简单的方式就是抛出slot

5、有些时候我希望渲染文本呢?有些时候我希望渲染字段的值而不涉及任何组件呢?

6、最后才是渲染对应的组件

那么,一个表单的结构化雏形就完成了。

<div class="schema-form">
    <el-form>
        <el-row>
            <el-col v-for="item in config" :key="item.key">
                <el-form-item>
                    <slot v-if="item.component === 'slot'" :name="item.slotName"></slot>
                    <div v-else-if="item.component === 'innerText'"></div>
                    <template v-else>
                        渲染对应组件,但需要对某些组件特殊处理
                    </template>
                </el-form-item>
            </el-col>
        </el-row>
    </el-form>
</div>

从上面的结构中,我们再来思考,我们的配置config数组的字段结构应该是什么样的。

配置数组数据结构

1、el-form 可能需要一些字段注入,作为最外层的组件,将传入schema form的字段都给它

2、el-form 需要传入一个数据源,这个数据源可以内部定义再传给外部,也可以传入一个对象,利用对象的特性做双向绑定,我选择了后者

3、el-col项可能有时不显示,所以config上扩展一个字段hidden,用于控制该项是否显示。

4、el-form-item的属性透传

5、innerText的样式定义

一些特殊的描述出来了,其余的再赘述,那么,config的数据结构就是这样

{
    key: '', // 当前字段的 key 值,同时会传到 el-form-item 的prop,不传数据验证和重置会失效
    label: '', // 当前 el-form-item 的label
    hidden: '', // 当前表单项是否展示
    labelWidth: '', // el-form-item 的label宽度
    component: '', // 支持 slot、innerText、Component,渲染成什么
    slotName: '', // compoment 为 slot 时,该值为对应slot的名字供外部使用
    innerClass: '', // component 为 innerText 时,给文本的样式,通常为全局样式
    innerStyle: '', // 同上
    innerText: '', // component 为 innerText 时,优先显示的文本,否则会显示当前的字段值
    itemProps: '', // 注入到 el-form-item 的属性
    props: '', // 当 component 为渲染组件时,注入到渲染组件当中的属性
    listeners: '', // 当 component 为渲染组件时,注入到渲染组件当中的事件
}

当把这些实现之后,其余需要扩展的功能可以自行实现,我这里也只是在业务中的扩展,并非完善的。

于是,我们的表单组件就变成了这样

<template>
  <div class="nx-form">
    <el-form
      ref="form"
      v-bind="$attrs"
      :model="source"
      class="nx-form"
    >
      <el-row :gutter="20">
        <el-col
          v-for="item in config"
          :key="item.key"
          :span="item.hidden ? 0 : item.span || 8"
        >
          <el-form-item
            v-if="!item.hidden"
            :label="item.label"
            :prop="item.key"
            :label-width="item.labelWidth || labelWidth || '120px'"
            v-bind="item.itemProps"
          >
            <slot v-if="item.component === 'slot'" :name="item.slotName"></slot>
            <div
              v-else-if="item.component === 'innerText'"
              :class="item.innerClass"
              :style="item.style"
            >
              {{ item.innerText || source[item.key] }}
            </div>
            <template v-else>
              <div class="nx-flex-align-center">
                <component
                  :is="item.component"
                  v-model="source[item.key]"
                  style="width: 100%;flex: 1;"
                  v-bind="item.props"
                  v-on="item.listeners"
                >
                  <template v-if="item.component === 'el-radio-group'">
                    <el-radio
                      v-for="(radio, radioIndex) in item.data"
                      :key="radioIndex"
                      style="margin-top: 10px;"
                      :label="radio.value"
                      :disabled="radio.disabled"
                    >
                      {{ radio.label }}
                    </el-radio>
                  </template>

                  <template v-if="item.component === 'el-checkbox-group'">
                    <el-checkbox
                      v-for="(checkbox, checkboxIndex) in item.data"
                      :key="checkboxIndex"
                      :label="checkbox.value"
                    >
                      {{ checkbox.label }}
                    </el-checkbox>
                  </template>

                  <template v-if="item.component === 'el-select'">
                    <el-option
                      v-for="(option, optionIndex) in item.data"
                      :key="optionIndex"
                      :label="option.label"
                      :value="option.value"
                    ></el-option>
                  </template>
                </component>
                <div
                  v-if="item.after"
                  class="nx-form__after"
                >
                  {{ item.after }}
                </div>
              </div>
              <div
                v-if="item.tips"
                class="nx-form__tips"
                v-html="item.tips"
              ></div>
            </template>

          </el-form-item>
          <!-- <div
            v-if="item.tips"
            :style="{ marginLeft: item.labelWidth || '120px' }"
            class="nx-form__tips"
            v-html="item.tips"
          ></div> -->
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>
export default {
  name: 'NxForm',
  components: {},
  props: {
    config: {
      type: Array,
      default: () => []
    },
    source: {
      type: Object,
      default: () => ({})
    }
  },
  methods: {
    resetFields() {
      this.$refs.form.resetFields();
    },
    clearValidate() {
      this.$refs.form.clearValidate();
    },
    async validate() {
      const valid = await this.$refs.form.validate();
      return valid;
    }
  }
};

可以看到,我扩展了一个data字段,用来作为el-select el-checkbox-group el-radio-group的数据源,这些特殊的组件单独列出就行了,基本上也之后有这么几个。

methods里也只是为了方便添加了一些常用的form方法,基本不做逻辑处理。

现在看一下,这样的配置可以生成怎样的表单

注意:我这里定义了一部分全局样式,比如在schema form下的组件,全部占满整格,使其比较美观。

生成这样一个常用的筛选项表单

<template>
  <div>
    <nx-form
      ref="searchForm"
      :source="searchForm"
      :config="searchConfig"
    >
      <div slot="search">
        <el-button type="primary" @click="$refs.nxTable.search(1)">查询</el-button>
        <el-button @click="reset()">重置</el-button>
      </div>
    </nx-form>
  </div>
</template>
<script>
export default {
  data() {
     searchForm: {
        keyWord: '', 
        newsType: '', 
        newsStatus: '', 
        publishTime: [],
        createTime: []
     },
  },
  computed: {
      searchConfig() {
      return [
        {
          key: 'keyWord',
          component: 'el-input',
          span: 8,
          label: '关键字',
          props: {
            placeholder: '标题/创建人',
            clearable: true
          }
        },
        {
          key: 'newsType',
          component: 'el-select',
          span: 8,
          label: '类型:',
          props: {
            placeholder: '请选择',
            clearable: true
          },
          data: this.newsTypes
        },
        {
          key: 'newsStatus',
          component: 'el-select',
          span: 8,
          label: '状态:',
          props: {
            placeholder: '请选择',
            clearable: true
          },
          data: statusTypes
        },
        {
          key: 'publishTime',
          component: 'el-date-picker',
          label: '发布时间:',
          span: 8,
          props: {
            clearable: true,
            valueFormat: 'timestamp',
            type: 'datetimerange',
            defaultTime: ['00:00:00', '23:59:59'],
            rangeSeparator: '-',
            startPlaceholder: '请选择开始时间',
            endPlaceholder: '请选择结束时间'
          }
        },
        {
          key: 'createTime',
          component: 'el-date-picker',
          label: '创建时间:',
          span: 8,
          props: {
            clearable: true,
            valueFormat: 'timestamp',
            type: 'datetimerange',
            defaultTime: ['00:00:00', '23:59:59'],
            rangeSeparator: '-',
            startPlaceholder: '请选择开始时间',
            endPlaceholder: '请选择结束时间'
          }
        },
        {
          component: 'slot',
          slotName: 'search',
          span: 8,
          labelWidth: '0'
        }
      ];
    }
  }
}
</script>

其余的找了一些,也没啥特别的,就不贴了,简单来说,这个百来行的组件,应用在多个大型项目当中,易用性,扩展性,没有出现什么问题,配合我们自定义的其他table组件、dialog组件,十分钟就可以实现一个完整的B端增删改查。

值得一提的是,为了表单的易用性,我们基本上所有的自定义组件都支持了使用v-model做数据绑定,达到简单易用的效果。

结语

代码是找了一个很久的项目写的一个思路,之后的项目中都有改进优化,大致只是分享一个思路,如果有什么想法的,欢迎指正。

 到此这篇关于Vue2 Element Schema Form 配置式生成表单的实现的文章就介绍到这了,更多相关Vue2 Element Schema Form生成表单内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Vue2ElementSchemaForm配置式生成表单的实现

本文链接: https://www.lsjlt.com/news/149426.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue2ElementSchemaForm配置式生成表单的实现
    目录前置知识点Component$attrs$listeners表单的结构是什么样的配置数组数据结构结语前置知识点 为了实现一个Schema Form配置式表单的生成,需要了解一部分...
    99+
    2024-04-02
  • golang 实现菜单树的生成方式
    golang 实现菜单树的生成,包括菜单节点的选中状态、半选中状态,菜单的搜索。 1 该包提供两个方法根接口 1.1 GenerateTree(nodes, selectedNode...
    99+
    2024-04-02
  • JavaScript element的Form表单生成方式
    目录设计目标配置化参数简单自由度我的实现过程表单项的格式设计v-bind的妙用computed的妙用:实现v-modeluseAttrs的妙用表单验证上传文件代码总结到底应不应该使用...
    99+
    2024-04-02
  • Vue实现生成二维码的简单方式
    目录前言①首先创建一个vue项目②引入qrcodejs2③封装组件1. 创建Vue文件2. 定义template模板3. 引入QRCode包4. 进行封装5. less控制样式④启动...
    99+
    2023-01-05
    前端vue生成二维码 vue生成二维码样式 vue生成二维码样式
  • Python中怎么实现列表生成式
    Python中怎么实现列表生成式,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 方法一是循环:L = [] for x in&...
    99+
    2023-06-15
  • python如何实现生成器表达式
    小编给大家分享一下python如何实现生成器表达式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!生成器表达式Python中的生成器是创建迭代器的一种简便方法。因为...
    99+
    2023-06-27
  • PHP实现动态表单生成工具详解
    目录Form介绍特点项目主页链接安装方法快速使用链式操作创建块表单数组配置创建块表单行内表单table表单表单包含多种input类型,包括 hiiden类型 ,text类型,radi...
    99+
    2024-04-02
  • 怎么在python中实现列表生成式
    怎么在python中实现列表生成式?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络...
    99+
    2023-06-14
  • EF使用CodeFirst模式生成单数形式表名
    使用Code-First模式生成数据库时,默认生成的数据库表的名称为类型的复数形式,例如实体类名称是"User",默认生成的数据库表名为“Users&...
    99+
    2024-04-02
  • 如何使用PHP实现动态表单生成工具
    小编给大家分享一下如何使用PHP实现动态表单生成工具,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!表单包含多种input类型,包括 hiiden类型 ,text类...
    99+
    2023-06-29
  • python3--列表推导式,生成器表达式,内置函数
    python列表推导式l = [i for i in range(10)] print(l) ll = ['选择{}'.format(i)&nb...
    99+
    2023-01-30
    生成器 表达式 函数
  • C++基于单链表实现学生成绩管理系统
    本文实例为大家分享了C++实现学生成绩管理系统的具体代码,供大家参考,具体内容如下 #include<iostream> using namespace std; s...
    99+
    2024-04-02
  • PHP实现一个表单-学生信息登记表单
    目录  一、前言 二、表单的定义的知识点讲解 1.定义表单 2.表单元素 三、代码段 1.表单的定义的代码 2、获取表单数据的代码 四、运行结果 1.DW编码界面 ​编辑2.网页运行界面 ​编辑3.填写内容实现跳转界面  一、前言 本文介...
    99+
    2023-08-31
    php dreamweaver servlet
  • vue和iview结合动态生成表单实例
    目录一、构建myform组建二、构建myFormItem组建三、构建函数式组件mycontrl组件四、用户输入的时候需要对表单项中进行各种验证或者逻辑五、表单输入完成获取表单中的值六...
    99+
    2022-11-13
    vue iview vue动态生成表单 vue iview生成表单
  • vue配置文件自动生成路由和菜单实例代码
    目录写在前面router.json路由生成菜单生成效果总结写在前面 每次重复写路由的时候是不是会觉得很烦,特别是项目大的时候,路由会有特别多,看都看不过来,所以这里我是有了一个ro...
    99+
    2024-04-02
  • 在Django中Pyecharts生成图表实现
    1 因为pyecharts是支持python的一种可视化,但是想要将其放入网页中,主要有两种方法 (1)在网页中假如iframe,将网页嵌在iframe中(该方法不具体描述) (2)...
    99+
    2024-04-02
  • 如何实现core文件自动生成配置文件
    这篇文章主要介绍如何实现core文件自动生成配置文件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体执行步骤如下:1.编辑环境配置文件,让shell启动时自动设置ulimitvi /etc/profile...
    99+
    2023-06-09
  • react 表单数据形式配置化设计
    目录前言实现一般实现配置化的实现实现思路具体实现使用示例总结前言 在日常的中后台系统开发中,表单是和我们打交道非常多的名词。但是在一般的表单实现中、我们会做着很多重复的工作,不停在写...
    99+
    2024-04-02
  • EF中怎么使用Code First模式生成单数形式表名
    今天小编给大家分享一下EF中怎么使用Code First模式生成单数形式表名的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2023-06-29
  • C++基于单链表如何实现学生成绩管理系统
    本文小编为大家详细介绍“C++基于单链表如何实现学生成绩管理系统”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++基于单链表如何实现学生成绩管理系统”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。具体代码如下#...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作