美文网首页ABPvue开发干货
vue antd 基于json schema 的动态表单实现 二

vue antd 基于json schema 的动态表单实现 二

作者: 诸葛_小亮 | 来源:发表于2018-11-04 09:36 被阅读40次

    介绍

    本篇文章主要介绍基于json schema 实现 vue antd 的动态表单中的第二部分:使用。


    运行结果

    展示表单是 antd-vue 官方的最后一个案例:antd form

    image.png
    image.png

    代码

    模板代码

    <template>
      <div>
      <dy-form :formSchema="schema" :uiSchema="uiSchema"
        @onSuccess="handleSuccess"
        :submiting="submiting"
      ></dy-form>
    
      </div>
    
    </template>
    
    

    使用dy-form标签,该标签主要包括以下属性

    • formSchema: form数据结构,主要是json schema对象,描述表单需要填写数据对象的结构
    • uiSchema: form ui 展示结构,是一个 ui schema 对象,描述如何显示表单
    • onSuccess: 表单提交成功执行的事件
    • submitting: 表单提交中的状态

    逻辑代码(ts)

    逻辑代码中主要包括两个属性:uiSchemaschema 根据这两个只读属性,可以正常展示表单

    
    <script  lang="tsx">
    import { Component, Prop, Vue } from 'vue-property-decorator';
    import { State, Mutation, namespace } from 'vuex-class';
    
    import DyForm from '@/components/dynamicform/DyForm.vue';
    
    @Component({
        components: {
          DyForm,
        },
    })
    export default class DynamicForm extends Vue {
    
      private form: any = null;
    
      private formItemLayout: any = {
        labelCol: {
          xs: { span: 24 },
          sm: { span: 7 },
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 12 },
          md: { span: 10 },
        },
      };
    
      get formData(): any {
        return {
          name: '关云长',
        };
      }
    
      // 动态表单 ui schema,描述表单展示
      get uiSchema(): any {
        return {
          name: {
            itemattrs: {
              ...this.formItemLayout,
            },
            widgetattrs: {
              placeholder: '请填写姓名',
            },
          },
          password: {
            errors: {
              minLength: '密码长度至少6位',
              maxLength: '密码长度最多10位',
              pattern: '密码必须是字母',
            },
          },
        };
      }
    
      // 动态表单 json schema,描述表单填写数据的数据结构
      get schema(): any {
        return {
          required: ['name'],
          properties: {
            name: {
              type: 'string',
              title: '姓名',
              ui: {
                errors: {
                  required: '姓名为必填项',
                },
              },
            },
            password: {
              type: 'string',
              title: '密码[长度|正则 验证]',
              minLength: 6,
              maxLength: 10,
              pattern: '^[A-Za-z]+$',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
              },
            },
            age: {
              type: 'number',
              title: '年龄',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                  min: 0,
                  max: 100,
                },
              },
            },
            age1: {
              type: 'number',
              title: '年龄1[最大最小值验证]',
              maximum: 100,
              minimum: 16,
              ui: {
                errors: {
                  minimum: '年龄必须满16',
                  maximum: '年龄必须小于100',
                },
                itemattrs: {
                  ...this.formItemLayout,
                },
              },
            },
            range: {
              type: 'daterange',
              title: '起止日期',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                  style: {width: '100%'},
                  placeholder: ['开始日期', '结束日期'],
                },
              },
            },
            remark: {
              type: 'textarea',
              title: '目标描述',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                  style: {'min-height': '32px'},
                  placeholder: '请输入你的阶段性工作目标',
                  rows: 4,
                },
              },
            },
            switch: {
              type: 'boolean',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
              },
            },
            slider: {
              type: 'slider',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                  marks: { 0: 'A', 20: 'B', 40: 'C', 60: 'D', 80: 'E', 100: 'F' },
                },
              },
            },
            rate: {
              type: 'rate',
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                  allowHalf: true,
                },
              },
            },
            select: {
              type: 'select',
              enum: [
                { label: 'Red', value: 'red'},
                { label: 'Green', value: 'green'},
                { label: 'Blue', value: 'blue'},
              ],
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                },
              },
            },
            select2: {
              type: 'select',
              title: 'Select[multiple]',
              enum: [
                { label: 'Red', value: 'red'},
                { label: 'Green', value: 'green'},
                { label: 'Blue', value: 'blue'},
              ],
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                  mode: 'multiple',
                },
              },
            },
            radio: {
              type: 'radio',
              title: 'radio',
              enum: [
                { label: 'item 1', value: 'a'},
                { label: 'item 2', value: 'b'},
                { label: 'item 3', value: 'c'},
              ],
              ui: {
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                },
              },
            },
            radio2: {
              type: 'radio',
              title: 'radio[button]',
              enum: [
                { label: 'item 1', value: 'a'},
                { label: 'item 2', value: 'b'},
                { label: 'item 3', value: 'c'},
              ],
              ui: {
                button: true,
                itemattrs: {
                  ...this.formItemLayout,
                },
                widgetattrs: {
                },
              },
            },
            file1: {
              type: 'string',
              title: '上传文件',
              ui: {
                widget: 'upload',
                itemattrs: {
                  ...this.formItemLayout,
                },
              },
            },
            file2: {
              type: 'string',
              title: '上传文件2',
              ui: {
                widget: 'uploaddragger',
                itemattrs: {
                  ...this.formItemLayout,
                },
              },
            },
          },
    
        };
      }
    
      private submiting: boolean = false;
    
      private handleSuccess(values: any) {
        // tslint:disable-next-line:no-console
        console.log(values);
    
        this.submiting = true;
        setTimeout(() => {
          this.submiting = false;
        }, 1000);
      }
    
    }
    </script>
    

    可以使用的动态组件

    目前只有几种常用的动态组件,如下所示

            // 日期范围
            registry.register('df-daterange', DateRangeWidget);
    
            // 数字输入框
            registry.register('df-number', NumberWidget);
    
            // 文本框
            registry.register('df-string', StringWidget);
            registry.register('df-text', TextWidget);
    
            // 区域文本框
            registry.register('df-textarea', TextareaWidget);
    
            // 开关
            registry.register('df-boolean', SwitchWidget);
    
            // 拖动条
            registry.register('df-slider', SliderWidget);
    
            // 星打分
            registry.register('df-rate', RateWidget);
    
            // 下拉框
            registry.register('df-select', SelectWidget);
    
            // 单选框
            registry.register('df-radio', RadioWidget);
    
            // 上传文件
            registry.register('df-upload', UploadWidget);
            registry.register('df-uploaddragger', UploadDraggerWidget);
    
    

    如果我们将ui shcmea 中的 widget 的type指定为 df-radio,则表示使用单选框渲染组件


    参考资料

    ng-alain-form
    json shcema
    antd-vue


    我的公众号

    abp爱好者

    相关文章

      网友评论

        本文标题:vue antd 基于json schema 的动态表单实现 二

        本文链接:https://www.haomeiwen.com/subject/dhgtxqtx.html