前端配置化表单组件设计方法

这篇具有很好参考价值的文章主要介绍了前端配置化表单组件设计方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

前端开发中涉及表单的页面非常多,看似功能简单,开发快速,实则占去了很大一部分时间。当某个表单包含元素过多时还会导致html代码过多,vue文件过大。从而不容易查找、修改和维护。为了提高开发效率及降低维护成本,下面介绍表单配置化组件的封装原理与封装方法。

二、技术方案

前端配置化表单组件设计方法

如上图所示,封装表单配置化组件的关键点有三个一是如何解决表单元素排布的行列问题,二是表单数据的绑定问题,三是表单元素的参数配置校验等问题。下面分别介绍这三个问题的解决方法。

•配置化表单组件的入参及说明

参数 说明 类型 可选值 默认值
labelWidth 表单元素label所占宽度 String —— 150px
columnList 表单元素所组成的配置,是一个数组 Array —— []
formData 表单元素值的集合 Object —— {}
columnSpan 表单排布分栏 Number —— 24
size 表单元素尺寸 String medium / small / mini medium

•计算配置化表单的行数,本表单通过基础的24分栏计算表单最终的行数和列数,通过下面方法最终得到一个关于行列的二维数组

newColumnList() {
  const newColumnList= []
  const row = Math.floor(24 / this.columnSpan)
  let newColumnItem = []
  for(let i=0; i< this.columnList.length; i++) {
    newColumnItem.push(this.columnList[i])
    if(newColumnItem.length === row || i === this.columnList.length-1) {
      newColumnList.push(newColumnItem)
      newColumnItem = []
    }
  }
  return newColumnList
}

•通过上面得到的二维数组进行循环渲染,首先循环渲染行,其次循环渲染列。本方案采用element中的表单,当然也可以用其他组件库或者原生表单进行渲染,其原理通用。最终将会根据参数column.type决定加载哪一个具体的表单元素。

<el-form ref="form" :model="formData" :label-width="labelWidth" :size="size">
    <el-row :gutter="20" v-for="(element,index) in newColumnList" :key="index+'formRow'">
      <template v-for="(item, index) in element" >
        <column
          :key="index + 'formView'"
          :columnSpan="columnSpan"
          :column="item"
          :formData="formData"
        />
      </template>
    </el-row>
</el-form>

•column组件最终根据type加载具体的表单元素。下面展示column组件的入参及其说明,通过component加载不同的表单元素

参数 说明 类型 可选值 默认值
column 表单元素的具体配置 Object —— {}
formData 表单元素值的集合 Object —— {}
columnSpan 表单排布分栏 Number —— 24
<el-col :span="columnSpan">
     <component
      :is="column.type + 'View'"
      :column="column"
      :formData="formData"
      v-model="formData[column.name]"
      :columnSpan="columnSpan"/>
 </el-col>

•这里主要以select表单元素为例进行说明,表单元素的双向绑定、校验以及值更新等问题

参数 说明 类型 可选值 默认值
column 表单元素的具体配置 Object —— {}
value 表单元素值 Number/String/Array —— ——

•column参数

参数 说明 类型 可选值 默认值
placeholder 空值说明 String —— ——
required 是否必填 Boolean —— ——
rules 校验规则 Array —— ——
title 表单元素label String —— ——
name 表单元素值名称 String —— ——
multiple 是否多选 Boolean —— ——
filterable 是否过滤 Boolean —— ——
disabled 是否禁用 Boolean —— ——
dictionary 下拉选项枚举 Array —— ——
changeFunction 值改变时的回调函数 Function —— ——
<el-form-item :label="column.title + ':'" :prop="column.name" :rules="rules">
    <el-select
      v-model="val"
      clearable
      :multiple="column.multiple"
      :filterable="column.filterable"
      :placeholder="'请选择' + column.title"
      :disabled="column.disabled"
      style="width: 100%"
      @change="onChange"
      @clear="onClear">
      <el-option v-for="item in column.dictionary" :key="item.code" :label="item.name" :value="item.code">
      </el-option>
    </el-select>
</el-form-item>

rules:  [
    {
      required: this.column.required,
      message: this.column.placeholder placeholder ? this.column.placeholder : `请输入${this.column.title}`,
      trigger: 'change'
    },
    ...this.column.rules
 ]

onChange(){
  this.$emit('input',this.val)
  if(this.column && this.column.changeFunction){
    this.column.changeFunction(this.val)
  }
},
onClear(){
  this.onChange()
}

三、项目实践

•配置化表单为bs-form,在页面中引入bs-form表单组件

<bs-form ref="formDemo"
     :columnList="columnList"
     :formData="formData"
     :columnSpan="columnSpan"
     labelWidth="120px">
</bs-form>
<el-row style="text-align: center;">
  <el-button type="primary"
             @click="onSave">保存</el-button>
  <el-button @click="onCancel">取消</el-button>
</el-row>

•formData参数

formData: {
    name: '',
    yearIncome: '', // 业务类型
    goodsCategoryId: '', // 托寄物品类id
    projectManagerErp: '', // 项目经理erp
    projectName: '', // 项目名称
    projectStage: '', // 项目阶段编码
    projectStandardName: '', // 标准名称
    projectYear: 2023, // 年份
    startRegionId: '', // 始发区域id
    startBattleId: '', // 始发战区id
    address: [], // 省市
    category: null, //图文类型
    range: [] //发布范围
 }

•分栏参数

columnSpan: 6

•表单配置参数

columnList(){
  const self = this
  return [
    {
      type: 'text',
      name: 'name',
      title: '项目名称',
      required: true,
      maxlength: 20,
      showwordlimit: true,
      placeholder: '请输入'
    },
    {
      name: 'category',
      type: 'radio',
      dictionary: [
        {
          code: 1,
          name: '类型一'
        },
        {
          code: 2,
          name: '类型二'
        }
      ],
      title: '图文类型',
      required: true
    },
    {
      name: 'range',
      type: 'checkbox',
      title: '发布范围',
      dictionary: [
        {
          code: 1,
          name: '范围一'
        },
        {
          code: 2,
          name: '范围二'
        }
      ],
      required: true
    },
    {
      type: 'text',  // 字段类型文本框
      name: 'yearIncome',  //与后台对接字段
      title: '年均收入',  // 前端展示字段
      required: true, // 必填项设置
      maxlength: 50,  // 字符串长度限制
      showwordlimit: true, // 是否显示字符串长度
      placeholder: '请输入', // 占位文本提示
      rules: [
        { pattern: /(^[1-9]([0-9]+)?(.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9].[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' }
      ],
    },
    {
      type: 'select',
      name: 'goodsCategoryId',
      title: '托寄物品类',
      required: true,
      filterable: true,
      placeholder: '请选择',
      dictionary: [{
        name: '苹果',
        code: '1'
      },{
        name: '手机',
        code: '2'
      },{
        name: '测试',
        code: '3'
      },{
        name: '樱桃',
        code: '7'
      },{
        name: '荸荠',
        code: '9'
      }]
    },
    {
      type: 'select',
      name: 'startRegionId',
      title: '区域',
      required: true,
      placeholder: '请选择',
      dictionary: [{
        name: '销售-华北区域',
        code: '1'
      },{
        name: '销售-华东区域',
        code: '2'
      },{
        name: '销售-华南区域',
        code: '3'
      },{
        name: '销售-西南区域',
        code: '4'
      },{
        name: '销售-华中区域',
        code: '5'
      },{
        name: '销售-东北区域',
        code: '6'
      }],
      // 点击下来触发切换联动的事件,为一个函数
      changeFunction: function (val) {
      }
    }, {
      type: 'select',
      name: 'startBattleId',
      title: '战区',
      required: true,
      placeholder: '请选择',
      dictionary: this.battleByRegionList
    }, {
      type: 'select',
      name: 'projectStage',
      title: '项目阶段',
      required: true,
      placeholder: '请选择',
      dictionary: [{
        name: '项目发起阶段',
        code: '10'
      },{
        name: '项目调研阶段',
        code: '20'
      },{
        name: '可行性分析阶段',
        code: '30'
      },{
        name: '立项阶段',
        code: '40'
      }]
    }, {
      type: 'text',
      name: 'projectStandardName',
      title: '标准名称',
      required: true,
      placeholder: '请输入',
      append: '.com',  // 文本框后置内容
    }, {
      type: 'text',
      name: 'projectManagerErp',
      title: '项目经理',
      required: true,
      placeholder: '请输入'
    },{
      type: 'cascader',  // 字段类型下拉框
      name: 'address',   //与后台对接字段
      title: '省市区',  // 前端展示字段
      required: true, // 必填项设置
      placeholder:'请选择',  // 占位文本提示
      dictionary: [{
        value: 'shanxi',
        label: '陕西省',
        children: [{
          value: 'xian',
          label: '西安市',
          children: [{
            value: 'yanta',
            label: '雁塔区'
          }, {
            value: 'beilin',
            label: '碑林区'
          }, {
            value: 'xincheng',
            label: '新城区'
          }, {
            value: 'weiyang',
            label: '未央区'
          }]
        }]
      }],
      // 点击下来触发切换联动的事件,为一个函数
      changeFunction: function(){}
    },{
      type: 'static',
      name: 'projectYear',
      title: '年份'
    }
  ]
}

•表单保存

// 保存
async onSave() {
  const valid = await this.$refs.formDemo.onValidate()
  if(valid) {
    this.$message.success('校验通过')
  }else {
    this.$message.error('校验失败')
  }
}

四、成果展示

前端配置化表单组件设计方法

作者:京东物流 田雷雷文章来源地址https://www.toymoban.com/news/detail-435077.html

到了这里,关于前端配置化表单组件设计方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Vue——formcreate表单设计器自定义组件实现(二)

    前面我写过一个自定义电子签名的formcreate表单设计器组件,那时初识formcreate各种使用也颇为生疏,不过总算套出了一个组件不是。此次时隔半年又有机会接触formcreate,重新熟悉和领悟了一番各个方法和使用指南。趁热打铁将此次心得再次分享。 本次要实现的自定义组件是一

    2024年02月14日
    浏览(49)
  • 前端使用视频作为背景图的方法

    通过 video + source 引入视频,并对视频播放属性进行设置,再通过 css 使视频覆盖背景即可。 👇觉得有帮助的朋友可以支持下作者哦,您的鼓励是我创作的最大动力,如有开发问题可联系作者

    2024年02月04日
    浏览(42)
  • VUE element-ui实现表格动态展示、动态删减列、动态排序、动态搜索条件配置、表单组件化。

        1、本组件支持列表的表头自定义配置,checkbox实现 2、本组件支持列表列排序,vuedraggable是拖拽插件,上图中字段管理里的拖拽效果 ,需要的话请自行npm install 3、本组件支持查询条件动态配置,穿梭框实现 https://download.csdn.net/download/askuld/88216937

    2024年01月16日
    浏览(60)
  • 什么是组件,以及前端各种框架组件的使用方法

    🙂博主:小猫娃来啦 🙂文章核心: 介绍什么是组件,以及前端各种框架组件的使用方法 ⭐组件就像是搭积木一样的东西,可以用来构建软件或者系统。每个组件都有自己独立的功能和任务,就像一个小小的部件。你可以把这些小部件组合在一起,形成一个完整的应用程序

    2024年02月12日
    浏览(47)
  • 前端实现el-pagination分页组件纯前端分页使用方法

    又是被后端欺负的一天,做了个公司的老项目,表格分页后端没法做,那就只能前端来完成。这里我介绍两种方法,需要的自提。 1、表格数据 2、分页定义属性 3、分页逻辑处理 4、初始化调用 1、表格数据处理 2、分页表格处理 3、分页定义属性 4、分页逻辑处理 两种方法都

    2024年02月15日
    浏览(48)
  • Vue3前端开发,如何获取组件内dom对象以及子组件的属性和方法

    Vue3前端开发,借助Ref来获取组件内dom对象,借助defineExpose编译宏可以获取到子组件的属性和方法。 app入口文件,我们作为父组件,在里面调用了自定义组件TestCom.vue。 先做了一个测试,借助于ref来访问自身的dom对象。如图所示是可以拿到的。 ref又称谓钩子函数,在vue2版本中

    2024年01月22日
    浏览(60)
  • 公司前端实习项目技术,可以借鉴一些组件设计思路及基本代码逻辑,应届生来!

    1.跳转 2.请求 1.mounted() 1.从登陆界面开始,通过Common.httpRequest()发送请求,经过Common.forward()跳转传参,在mounted或者created生命周期中通过common.getActivePageStack()获取到跳转所传参数,这样就可以根据id或者其他唯一数据发送请求查询所需数据 1.DialogInfo 1.用法 先引入组件 在

    2024年02月21日
    浏览(53)
  • 低代码配置-列表页组件设计

    保存 表单属性存放 — bill 筛选项配置存放 — filterLayout 列表按钮存放 — buttonLayout 列表布局存放 — listLayout api存放 — api 数据结构 表单属性数据来源 建议从保存数据中直接修改,利用对象的存放规则;按照这个思路,我们可以从组件列表中将所需要的配置抛出( 整理成单个

    2024年01月17日
    浏览(14)
  • 【前端】解决element-ui的form组件resetFields()方法不生效的问题

    使用 element-ui 的 form 组件,在输入栏较多的时候,有时 resetFields 只能重置一部分输入框的值 给每个值赋值初始值为空即可 例如,需要清除的 :model=\\\"queryForm.bgnTime\\\" 、 :model=\\\"queryForm.endTime\\\" 等一系列的值,那么就不要只定义 queryForm:{} ,而是要把对象下的各个属性赋值初值为空

    2024年02月15日
    浏览(54)
  • 05-微信小程序常用组件-表单组件

    05-微信小程序常用组件-表单组件 微信小程序包含了六大组件: 视图容器 、 基础内容 、 导航 、 表单 、 互动 和 导航 。这些组件可以通过WXML和WXSS进行布局和样式设置,从而构建出丰富的小程序界面和交互体验。 其中,视图容器组件包括view和scroll-view等,用于实现页面的

    2024年02月12日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包