动态生成表单-dynamic-form-check

930 阅读10分钟

动态生成表单

介绍

dynamic-form-check 是基于vue.js ,element-ui 的前端动态表单渲染器,可通过配置文件快速的生成 form 表单,表单组件是无状态的。

image.png

image.png

安装

npm包

npm i dynamic-form-check
# or
yarn add dynamic-form-check

form表单参数配置

参数说明类型可选值默认值
dynamicFormProps整个表单的配置数据object{formProps:{},itemProps:{},}---
formPropsform表单的配置object{size: "small",labelWidth: "140px",}---
ruleFormform表单数据对象object------
size用于控制该表单内组件的尺寸stringmedium / small / mini---
inline行内表单模式boolean---false
labelPosition表单域标签的位置,如果值为 left 或者 right 时,则需要设置 labelWidthstringright/left/topright
labelWidth表单域标签的宽度,例如 '50px'。作为 Form 直接子元素的 form-item 会继承该值。支持 autostring------
labelSuffix表单域标签的后缀string------
hideRequiredAsterisk是否隐藏必填字段的标签旁边的红色星号boolean---false
showMessage是否显示校验错误信息boolean---true
inlineMessage是否以行内形式展示校验信息boolean---false
statusIcon是否在输入框中显示校验结果反馈图标boolean---false
validateOnRuleChange是否在 rules 属性改变后立即触发一次验证boolean---true
disabled是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效boolean---false
itemProps动态生成form表单的数据对象object{type: "input",label: "输入框",prop: "input",maxlength: 50,col: 24,setProp: {minlength: 10,},rule: {required: true,message: "请输入名称",trigger: "blur",},}false

input输入框

参数说明类型可选值默认值
type类型stringinput---
label标签的label名string------
prop当前表单绑定的校验名string------
placeholder占位符string---请输入label
maxlength原生属性,最大输入长度number------
colrow-col布局number---24
rows输入框行数,只对 type="textarea" 有效number2
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
autofocus原生属性,自动获取焦点booleantrue, falsefalse
setProp拓展可传参数object------
setProp------------
type类型stringnumbder/text/textareatext
clearable是否可清空booleantrue
showassword是否显示切换密码图标booleanfalse
disabled禁用booleanfalse
size输入框尺寸stringmedium / small / mini
prefix-icon输入框头部图标string
suffix-icon输入框尾部图标string
autosize自适应内容高度,只对 type="textarea" 有效,可传入对象,如,{ minRows: 2, maxRows: 6 }boolean / objectfalse
autocomplete原生属性,自动补全stringon, offoff
readonly原生属性,是否只读booleanfalse
validate-event输入时是否触发表单的校验boolean-true

select选择器

参数说明类型可选值默认值
type类型select---
label标签的label名string------
prop当前表单绑定的校验名string------
placeholder占位符string---请选择label
colrow-col布局number---24
autofocus原生属性,自动获取焦点booleantrue, falsefalse
selectOptionoptions的值Array[{ value: '选项1', label: '黄金糕' }][]
setProp拓展可传参数object------
setProp------------
multiple是否多选booleanfalse
size输入框尺寸stringmedium/small/mini
clearable是否可以清空选项booleanfalse
collapseTags多选时是否将选中值按文字的形式展示booleanfalse
multipleLimit多选时用户最多可以选择的项目数,为0则不限制number0
nameselectinput的name属性string
placeholder占位符string请选择
filterable是否可搜索booleanfalse
allowCreate是否允许用户创建新条目,需配合 filterable 使用booleanfalse
filterMethod自定义搜索方法function
remote是否为远程搜索booleanfalse
remoteMethod远程搜索方法function
loading是否正在从远程获取数据booleanfalse
loadingText远程加载时显示的文字string加载中
noMatchText搜索条件无匹配时显示的文字string无匹配数据
noDataText选项为空时显示的文字string无数据
popperClassSelect下拉框的类名string
reserveKeyword多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词booleanfalse
defaultFirstOption在输入框按下回车,选择第一个匹配项。需配合 filterable 或 remote 使用boolean-false
popperAppendToBody是否将弹出框插入至body元素。在弹出框的定位出现问题时,可将该属性设置为falseboolean-true
automaticDropdown对于不可搜索的Select,是否在输入框获得焦点后自动弹出选项菜单boolean-false

cascader级联选择器

参数说明类型可选值默认值
type类型cascader---
label标签的label名string------
prop当前表单绑定的校验名string------
placeholder占位符string---请选择label
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
selectOption可选项数据源,键名可通过 Props 属性配置array
setProp拓展可传参数object------
setProp------------
size尺寸stringmedium/small/mini
disabled是否禁用booleanfalse
clearable是否支持清空选项booleanfalse
showAllLevels输入框中是否显示选中值的完整路径booleantrue
collapseTags多选模式下是否折叠Tagboolean-false
separator选项分隔符string斜杠'/'
filterable是否可搜索选项boolean
filterMethod自定义搜索逻辑,第一个参数是节点node,第二个参数是搜索关键词keyword,通过返回布尔值表示是否命中function(node,keyword)--
debounce搜索关键词输入的去抖延迟,毫秒number300
beforeFilter筛选之前的钩子,参数为输入的值,若返回false或者返回Promise且被reject,则停止筛选function(value)
popperClass自定义浮层类名string
props配置选项,具体见下表object
props------------
expandTrigger次级菜单的展开方式stringclick/hover'click'
multiple是否多选boolean-false
checkStrictly是否严格的遵守父子节点不互相关联boolean-false
emitPath在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置false,则只返回该节点的值boolean-true
lazy是否动态加载子节点,需与lazyLoad方法结合使用boolean-false
lazyLoad加载动态数据的方法,仅在lazy为true时有效function(node,resolve),node为当前点击的节点,resolve为数据加载完成的回调(必须调用)--
value指定选项的值为选项对象的某个属性值string'value'
label指定选项标签为选项对象的某个属性值string'label'
children指定选项的子选项为选项对象的某个属性值string'children'
disabled指定选项的禁用为选项对象的某个属性值string'disabled'
leaf指定选项的叶子节点的标志位为选项对象的某个属性值string'leaf'

radio单选框

参数说明类型可选值默认值
type类型radio---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
selectOption可选项数据源array[{value:'备注项3',label:'1111',border:true,type:'button',disabled:true}]
setProp拓展可传参数object------
setProp------------
size尺寸stringmedium/small/mini
disabled是否禁用booleanfalse

checkbox多选框

参数说明类型可选值默认值
type类型checkbox---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
selectOption可选项数据源array[{label: "备注项3",border: true,type: "button",disabled: true,}]
setProp拓展可传参数object------
setProp------------
label选中状态的值(只有在checkbox-group或者绑定对象类型为array时有效)string/number/boolean
trueLabel选中时的值string/number
falseLabel没有选中时的值string/number
disabled是否禁用booleanfalse
border是否显示边框booleanfalse
sizeCheckbox的尺寸,仅在border为真时有效stringmedium/small/mini
checked当前是否勾选booleanfalse
indeterminate设置indeterminate状态,只负责样式控制booleanfalse

switch开关

参数说明类型可选值默认值
type类型switch---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
setProp拓展可传参数object------
setProp------------
disabled是否禁用booleanfalse
widthswitch的宽度(像素)number40
activeIconClassswitch打开时所显示图标的类名,设置此项会忽略 active-textstring
inactiveIconClassswitch关闭时所显示图标的类名,设置此项会忽略 inactive-textstring
activeTextswitch打开时的文字描述string
inactiveTextswitch关闭时的文字描述string
activeValueswitch打开时的值boolean/string/numbertrue
inactiveValueswitch关闭时的值boolean/string/numberfalse
activeColorswitch打开时的背景色string#409EFF
inactiveColorswitch关闭时的背景色string#C0CCDA
validateEvent改变switch状态时是否触发表单的校验boolean-true

slider滑块

参数说明类型可选值默认值
type类型slider---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
setProp拓展可传参数object------
setProp------------
min最小值number0
max最大值number100
disabled是否禁用booleanfalse
step步长number1
showInput是否显示输入框,仅在非范围选择时有效booleanfalse
showInputControls在显示输入框的情况下,是否显示输入框的控制按钮booleantrue
inputSize输入框的尺寸stringlarge/medium/small/minismall
showStops是否显示间断点booleanfalse
showTooltip是否显示tooltipbooleantrue
formatTooltip格式化tooltipmessagefunction(value)
range是否为范围选择booleanfalse
vertical是否竖向模式booleanfalse
heightSlider高度,竖向模式时必填string
label屏幕阅读器标签string
debounce输入时的去抖延迟,毫秒,仅在show-input等于true时有效number300
tooltipClasstooltip的自定义类名string
marks标记,key的类型必须为number且取值在闭区间 [min,max] 内,每个标记可以单独设置样式object

date-time-picker日期时间选择器

参数说明类型可选值默认值
type类型date-time-picker---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
setProp拓展可传参数object------
setProp------------
readonly完全只读booleanfalse
disabled禁用booleanfalse
editable文本框可输入booleantrue
clearable是否显示清除按钮booleantrue
size输入框尺寸stringlarge,small,mini
startPlaceholder范围选择时开始日期的占位内容string
endPlaceholder范围选择时结束日期的占位内容string
timeArrowControl是否使用箭头进行时间选择booleanfalse
type显示类型stringyear/month/date/week/datetime/datetimerange/daterangedate
format显示在输入框中的格式string日期格式yyyy-MM-ddHH:mm:ss
align对齐方式stringleft,center,rightleft
popperClassDateTimePicker下拉框的类名string
pickerOptions当前时间日期选择器特有的选项参考下表object{}
rangeSeparator选择范围时的分隔符string-'-'
defaultValue可选,选择器打开时默认显示的时间Date可被newDate()解析
defaultTime选中日期后的默认具体时刻非范围选择时:string/范围选择时:string[]非范围选择时:形如12:00:00的字符串;范围选择时:数组,长度为2,每项值为字符串,形如12:00:00,第一项指定开始日期的时刻,第二项指定结束日期的时刻。不指定会使用时刻 00:00:00
valueFormat可选,绑定值的格式。不指定则绑定值为Date对象string日期格式
unlinkPanels在范围选择器里取消两个日期面板之间的联动booleanfalse
prefixIcon自定义头部图标的类名stringel-icon-date
clearIcon自定义清空图标的类名stringel-icon-circle-close
pickerOptions-------—------
disabledDate设置禁用状态,参数为当前日期,要求返回 BooleanFunction设置开始时间:pickerOptions: {disabledDate: (time) => {return (time.getTime() >new Date(this.dynamicFormProps.formProps.ruleForm.endDate).getTime());},},设置结束时间:pickerOptions: {disabledDate: (time) => {return (time.getTime() <new Date(this.dynamicFormProps.formProps.ruleForm.startDate).getTime() -1 * 24 * 60 * 60 * 1000);},},---

input-number计数器

参数说明类型可选值默认值
type类型input-number---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
placeholder输入框默认placeholderstring--
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
setProp拓展可传参数object------
setProp------------
min设置计数器允许的最小值number-Infinity
max设置计数器允许的最大值numberInfinity
step计数器步长number1
stepStrictly是否只能输入step的倍数booleanfalse
precision数值精度number
size计数器尺寸stringlarge,small
disabled是否禁用计数器booleanfalse
controls是否使用控制按钮booleantrue
controlsPosition控制按钮位置stringright-
label输入框关联的label文字string

rate评分

参数说明类型可选值默认值
type类型rate---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
setProp拓展可传参数object------
setProp------------
max最大分值number5
disabled是否为只读booleanfalse
allowHalf是否允许半选booleanfalse
lowThreshold低分和中等分数的界限值,值本身被划分在低分中number2
highThreshold高分和中等分数的界限值,值本身被划分在高分中number4
colorsicon的颜色。若传入数组,共有3个元素,为3个分段所对应的颜色;若传入对象,可自定义分段,键名为分段的界限值,键值为对应的颜色array/object['#F7BA2A','#F7BA2A','#F7BA2A']
voidColor未选中icon的颜色string#C6D1DE
disabledVoidColor只读时未选中icon的颜色string#EFF2F7
iconClassesicon的类名。若传入数组,共有3个元素,为3个分段所对应的类名;若传入对象,可自定义分段,键名为分段的界限值,键值为对应的类名array/object['el-icon-star-on','el-icon-star-on','el-icon-star-on']
voidIconClass未选中icon的类名stringel-icon-star-off
disabledVoidIconClass只读时未选中icon的类名stringel-icon-star-on
showText是否显示辅助文字,若为真,则会从texts数组中选取当前分数对应的文字内容booleanfalse
showScore是否显示当前分数,show-score和show-text不能同时为真booleanfalse
textColor辅助文字的颜色string#1F2D3D
texts辅助文字数组array['极差','失望','一般','满意','惊喜']
scoreTemplate分数显示模板string{value}

color-picker颜色选择器

参数说明类型可选值默认值
type类型 color-picker---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
setProp拓展可传参数object------
setProp------------
disabled是否禁用booleanfalse
size尺寸stringmedium/small/mini
showAlpha是否支持透明度选择booleanfalse
colorFormat写入v-model的颜色的格式stringhsl/hsv/hex/rgbhex(showAlpha为false)/rgb(showAlpha为true)
popperClassColorPicker下拉框的类名string
predefine预定义颜色array

自定义插槽

参数说明类型可选值默认值
带标签的slot------------
type类型itemSlot---
label标签的label名string------
prop当前表单绑定的校验名string------
colrow-col布局number---24
rule表单验证规则object{required: true,message: "请输入名称",trigger: "blur",}---
slotName插槽名称string------
不带标签的slot------------
type类型slot---
slotName插槽名称string------

表单方法

//校验表单的触发

submit() { 
    this.$refs.ruleForm.validate((valid) => {
        console.log(this.dynamicFormProps.formProps.ruleForm, "valid"); 
    }); 
 }

//表单发生改变处罚的钩子
formEvent(e) { console.log(e, "e"); },
<template>
  <div>
    <h1>动态生成表单</h1>
    <dynamic-form :dynamicFormProps="dynamicFormProps" @formEvent="formEvent">
      <el-upload
        slot="uploadSlot"
        class="upload-demo"
        action="https://jsonplaceholder.typicode.com/posts/"
        multiple
        :limit="3"
        :file-list="fileList"
      >
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">
          只能上传jpg/png文件,且不超过500kb
        </div>
      </el-upload>
      <el-button slot="buttonSlot">不带标签的slot</el-button>
    </dynamic-form>
    <el-button type="primary" @click="submit">提交</el-button>
  </div>
</template>

<script>
import DynamicForm from "@/components/DynamicForm/index.js";
import AreaJson from "@/pubilc/area.json";
export default {
  components: { DynamicForm },
  data() {
    return {
      dynamicFormProps: {
        formProps: {
          size: "small",
          labelWidth: "140px",
          ruleForm: {},
        },
        itemProps: [
          {
            type: "input",
            label: "输入框",
            prop: "input",
            maxlength: 50,
            autofocus: true,
            col: 24,
            setProp: {
              clearable: true,
              type: "number",
            },
            rule: {
              required: true,
              message: "请输入活动名称",
              trigger: "blur",
            },
          }, // 输入框
          {
            type: "select",
            label: "下拉框",
            prop: "select",
            col: 24,
            setProp: {
              clearable: true,
              multiple: true,

              // collapseTags: false,
              // multipleLimit: 2,
              filterable: true,
              // allowCreate: true,
              // filterMethod: this.query,
              remote: true,
              // remoteMethod:this.remoteMethod,
              // loading:true,
              // loadingText:'1111'
              // noMatchText: "你好",
              // popperClass:'你好',
              reserveKeyword: true,
              // defaultFirstOption:true,
              // popperAppendToBody:true,
              automaticDropdown: true,
            },
            selectOption: [
              {
                id: 0,
                name: "黄金糕",
              },
              {
                id: 1,
                name: "黄金糕1111",
              },
              {
                id: 2,
                name: "黄金糕222",
              },
            ],
            defaultProps: { label: "name", value: "id" },
          }, // 下拉框
          {
            type: "cascader",
            label: "省市区",
            prop: "cascader",
            col: 24,
            selectOption: AreaJson,
            setProp: {
              props: {
                expandTrigger: "hover",
                value: "name",
                label: "name",
              },
            },
          }, // 级联选择器
          {
            type: "input",
            label: "文本域",
            prop: "textarea",
            maxlength: 500,
            setProp: {
              type: "textarea",
              clearable: true,
              autosize: { minRows: 2, maxRows: 4 },
            },
            col: 24,
          }, // 文本域
          {
            type: "radio",
            label: "单选框",
            prop: "radio",
            col: 24,
            setProp: {
              disabled: false,
              size: "medium",
            },
            selectOption: [
              { value: "备注项1", label: "1111", border: true, type: "button" },
              { value: "备注项2", label: "1111", border: true, type: "button" },
              {
                value: "备注项3",
                label: "1111",
                border: true,
                type: "button",
                disabled: true,
              },
            ],
          }, // Radio 单选框
          {
            type: "checkbox",
            label: "多选框",
            prop: "checkbox",
            col: 24,
            setProp: {
              disabled: false,
              // size: "medium",
            },
            selectOption: [
              { label: "备注项1", border: false, type: "button" },
              { label: "备注项2", border: true },
              {
                label: "备注项3",
                border: true,
                type: "button",
                disabled: true,
              },
            ],
          }, //多选框
          {
            type: "switch",
            label: "开关",
            prop: "switch",
            col: 24,
            setProp: {
              disabled: false,
              // width:200,
              // activeText:'what?',
              // inactiveText:'niiiiii',
              // activeValue:'llll',
              // activeColor:'#000'
            },
          }, //开关
          {
            type: "slider",
            label: "滑块",
            prop: "slider",
            col: 24,
            setProp: {
              disabled: false,
              min: 10,
              max: 1000,
              step: 10,
              showInput: true,
              // showInputControls:false,
              // inputSize:'large',
              // showStops:true,
              // showTooltip:false,
              // formatTooltip:this.formatTooltip,
              // range:true,
              // vertical:true,
              // height:'200px',
              // label:'9999',
              debounce: 5000,
            },
          }, //滑块
          {
            type: "date-time-picker",
            label: "开始日期",
            prop: "startDate",
            col: 24,
            setProp: {
              // readonly:true,
              clearable: true,
              // startPlaceholder:'ppp',
              // type: "datetime",
              // format: "yyyy-MM-ddHH:mm:ss",
              // timeArrowControl: true,
              pickerOptions: {
                disabledDate: (time) => {
                  return (
                    time.getTime() >
                    new Date(
                      this.dynamicFormProps.formProps.ruleForm.endDate
                    ).getTime()
                  );
                },
              },
            },
          }, //日期时间
          {
            type: "date-time-picker",
            label: "结束日期",
            prop: "endDate",
            col: 24,
            setProp: {
              // readonly:true,
              clearable: true,
              // startPlaceholder:'ppp',
              // type: "datetime",
              // format: "yyyy-MM-ddHH:mm:ss",
              // timeArrowControl: true,
              pickerOptions: {
                disabledDate: (time) => {
                  console.log(
                    this.dynamicFormProps.formProps.ruleForm,
                    "dynamicFormProps"
                  );
                  return (
                    time.getTime() <
                    new Date(
                      this.dynamicFormProps.formProps.ruleForm.startDate
                    ).getTime() -
                      1 * 24 * 60 * 60 * 1000
                  );
                },
              },
            },
          }, //日期时间
          {
            type: "input-number",
            label: "计数器",
            prop: "input-number",
            col: 24,
            setProp: {
              disabled: false,
              min: 10,
              max: 1000,
              size: "large",
              controlsPosition: "right",
            },
          }, //计数器
          {
            type: "rate",
            label: "评分",
            prop: "rate",
            col: 24,
            setProp: {
              lowThreshold: 3,
              allowHalf: true,
              colors: ["#000"],
              voidColor: "pink",
            },
          }, //评分
          {
            type: "color-picker",
            label: "颜色选择",
            prop: "color-picker",
            col: 24,
            setProp: {
              disabled: false,
              showAlpha: false,
              colorFormat: "hex",
            },
          }, //颜色
          {
            type: "slot",
            slotName: "buttonSlot",
          }, // 不带标签的自定义
          {
            type: "itemSlot",
            label: "带标签的自定义",
            prop: "itemSlot",
            col: 24,
            slotName: "uploadSlot",
          }, // 带标签的自定义
        ],
      },
      fileList: [
        {
          name: "food.jpeg",
          url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
        },
      ],
    };
  },
  methods: {
    formEvent(e) {
      console.log(e, "e");
    },
    submit() {
      this.$refs.ruleForm.validate((valid) => {
        console.log(valid, "valid");
        console.log(this.dynamicFormProps.formProps.ruleForm, "valid");
      });
    },
    query(value) {
      console.log(value, "iiiii");
    },
    remoteMethod(va) {
      console.log(va, "222");
    },
    formatTooltip(value) {
      console.log(value, "llll");
    },
  },
};
</script>

<style lang="less" scoped></style>