VueFormGenerator 轻松配置表单~

介绍

之前项目中使用到一个好用表单生成插件VueFormGenerator,项目中使用表单的场景很多,创建表单基本占据了一半的工作量,代码中涵盖了大量的表单元素,结合这个插件,利用ui组件封装自定义的表单组件,实现灵活配置表单内容,使用表单非常轻松..

VueFormGenerator是用于Vue的基于架构的表单生成器组件。基本效果如图, 它是利用配置表单元素结合内置组件生成表单,Model则为表单绑定的数据 文档地址

image.png

基本使用

简单介绍:VueFormGenerator组件由四个模块组成(schema 模块 , model 数据 , options 配置 , event 事件),结合组件提供一些基本的表单字段,检验方式生成表单,上图实现方式可以按照文档配置实现 下面为具体介绍我个人使用,效果图(仅展示个别字段,内容经删减)

Snipaste_2021-12-13_17-47-19.png

安装及注册 npm install --save vue-form-generator

  import FormGeneratorConfig from "./lib/FormGeneratorConfig"; //自定义的校验方式
  import VueFormGenerator from 'vue-form-generator'
  import 'vue-form-generator/dist/vfg.css' //内置css样式,可以更改为自己的样式
  Vue.use(VueFormGenerator, FormGeneratorConfig);
复制代码

注册自定义组件

//在component文件夹创建fieldConfig.js,这里拿自定义的input组件做例子

import Vue from 'vue'
import fieldInput from './types/fieldInput.vue';
Vue.component('fieldAInput', fieldInput);
复制代码

自定义组件

//在component下的types文件夹创建fieldInput.vue,这里拿自定义的input组件做例子

//ComFormWarp为外层包裹div,做添加标题和类名
<template>
  <ComFormWarp :title="schema.title" :className="schema.className">
    <div class="ant-form-item-control">
      <span class="ant-form-item-children">
        <a-input
          :placeholder="schema.placeholder"
          :type="schema.inputType"
          :addonBefore="schema.addonBefore || ''"
          :disabled="schema.writeable || schema.disabled"
          v-model="value"
          @change="change"
          :id="schema.model"
        >
          <a-icon slot="suffix" type="check" style="color:#40d354" v-if="schema.slot" />

        </a-input>
      </span>
      <div class="ant-form-explain" v-if="schema.desc">{{schema.desc}}</div>
    </div>
  </ComFormWarp>
</template>
复制代码

自定义校验

自定义校验文件FormGeneratorConfig.js

export default {
    validators: {
      newValidator: (value, field, _model) => {
        if (!value && field.required) {
          return field.title?`${field.title} 是必填项!`:`必填项,不容许为空`;
        }
        if (value && field.max) {
          let reg = value.length > field.max;
          if (reg) {
            return `${field.title}有效长度为${field.max}位`;
          } else {
            return [];
          }
        }
        return [];
      },
      arrayValidator: (value, field, _model) => {
        if (value && value.length < 1) {
          return `${field.title} 是必填项!`;
        } else {
          return [];
        }
      },
    },
  }
复制代码
  在组件中使用
  <template>
   <vue-form-generator
        class="register-box"
        tag="div"
        :model="model"
        :schema="schema"
        :options="formOptions"
        @validated="onValidated"
      ></vue-form-generator>
  </template>
  
export default {
  data () {
    return {
     //数据,需保证定义的key
      model: {
        type: '',
        name: '',
        logo: '',
        source: '',
        desc: '',
        system: []
      },
      //字段配置,fields所使用的字段使用antd组件封装并使用自定义字段 例a-select
      schema: {
        groups: [
          {
            legend: "基础信息",
            fields: [
              {
                type: "a-select",
                title: "类型",
                model: "type",
                required: true,
                validator: ["newValidator"],
                options: this.TypeList || [],
                writeable: false,
                placeholder: "请选择类型",
                className: "ant-col-xs-24 ant-col-sm-6 ant-col-sm-12",
              },
              {
                type: "a-input",
                title: "名称",
                model: "name",
                desc:"名称由字母,数字,下划线,点,中划线和汉字组成,最大20个字符",
                placeholder: "请输入名称",
                className: "ant-col-xs-24 ant-col-sm-6 ant-col-sm-12",
                required: true,
                max: 20,
                validator: ["NameVaild"],
                visible: function(model: { type: string }) {
                  return (
                    model.type == "1" || model.type == "2"
                  );
                },
                //visible举例,可以切换类型显示事件,类似v-show
                onChanged: (model, newVal, oldVal, field) => {
                if (newVal) {
                   //do sth
                }
                //onChanged举例,切换值的change事件
              },
               },
              {
                type: "a-img-upload",
                title: "logo",
                model: "logo",
                className: "ant-col-xs-24 ant-col-sm-6 ant-col-sm-12",
                required: true,
                validator: ["newValidator"],
              },
              {
                type: "a-radio",
                title: "来源",
                model: "source",
                placeholder: "请输入名称",
                options: [
                  {label: "线上",value: "1"},
                  {label: "线下",value: "2"},
                  {label: "第三方",value: "3"},
                ],
                className: "ant-col-xs-24 ant-col-sm-6 ant-col-sm-12",
                required: true,
                validator: ["newValidator"],
              },
              {
                type: "a-textarea",
                title: "简介",
                model: "desc",
                required: true,
                validator: ["newValidator"],
                max: 1000,
                placeholder: "介绍",
                className: "ant-col-xs-24 ant-col-sm-6 ant-col-sm-12",
                rows: 4,
              },
              {
                type: "a-checkbox",
                title: "操作系统",
                model: "operate_system",
                required: true,
                validator: ["checkValidator"],
                className: "ant-col-xs-24 ant-col-sm-6 ant-col-sm-12",
                options: [
                  { label: "iOS", value: "iOS" },
                  { label: "Android", value: "Android" },
                  { label: "windows", value: "windows" },
                  { label: "BlackBerry", value: "BlackBerry" },
                 ]
               },
              //自定义按钮
              {
                type: "submit",
                buttonText: "下一步",
                onSubmit: this.submit,
                validateBeforeSubmit: true,
               },
              {
                type: "submit",
                buttonText: "保存草稿",
                styleClasses: "ant-btn-save",
                onSubmit: this.draft,//保存草稿和提交方法,这里省略,可以自行补充
               },
            ]
          }
        ]
      },
      formOptions: {
        validateAfterChanged: true,//model数据改变触发校验
      }
    }
  }
  methods:{
      //自动定位到校验错误的字段
      onValidated(isValid, errors, $event) {
         if (errors && errors.length > 0) {
         const model = errors[0].field.model;
         const field = errors.find((err: any) => {
          return err.field.model == model;
        });
        const element = document.querySelector(`#${field.field.model}`);
        if (element) {
          element.scrollIntoView({
           //滚动到指定节点
           block: "center",
           behavior: "auto",
          });
        }
       }
     }
  }
}
复制代码

最后就能成功生成表单了

Snipaste_2021-12-13_17-47-19.png

以上例子删减了大部分内容QAQ,仅基本实现展示效果,可能会缺少某些配置和局限性 (样式和其他字段就不贴出来),还有更多拓展功能可以通过配置去实现如动态增减表单项,添加自定义事件等,这个有兴趣的朋友可以试试,以上就是简单介绍VueFormGenerator的基本用法,日常表单应用能更加方便~

猜你喜欢

转载自juejin.im/post/7041493756276637726