Vue 3.x Form render_Vue 3.x Form render


为什么要造这个轮子?

之前用过 React 的 Form Render 的小伙伴应该比较清楚 Form Render 可以基于 JSON Schema 快速构建出表单区块。不得不说 For Render 在以下场景中的使用会给开发带来巨大的便利:

  1. 规范化表单视图的快速生成:写好对应的参数配置,快速生成一个标准表单,省去了使用类 Ant Design 表单的麻烦地方
  2. 可视化配置界面生成:并可以从代码层面 自动生成 JSON Schema,来完成整体流程的打通
  3. 服务能力配置界面生成:常用于后台字段系统中,接口同学通过吐 JSON Schema 字段给前端界面,渲染出他所想要的界面以及获取用户的输入进行提交给后端,可以起到无需发布就可无缝扩展各种类型的作用
  4. 作为配置输入和搭建系统配合使用:FormRender 在正常展示的情况下,可以很简单的进行和原主题的适配使用

但是现在我们的场景是基于 vue 3.x 的框架基础上去使用 form render 但是 form render 目前也只支持 react。然后我再 Google 上搜了一大圈,也没找到一个还可以的 vue 3.x的 form render,不过 vue 2.x 的还是挺多的。出于这样的诉求,自己动手撸了一个。

功能

vue-form-render 是基于 Form Render 基本能力作为原型实现的 Vue 3.x 版本的表单渲染器,目前支持 90% 左右的 Form Render 功能,后续会不断的维护支持。

Array

  • 支持excel导入数据,方便快快捷生成form Data
  • 支持拖拽排序
"listName2": {  "title": "对象数组",  "description": "对象数组嵌套功能",  "type": "array",  "minItems": 1,  "maxItems": 3,  "ui:displayType": "row",  "items": {"type": "object","properties": {      "input1": {"title": "简单输入框","type": "string"  },      "selet1": {"title": "单选","type": "string","enum": [          "a",          "b",          "c"],"enumNames": [          "早",          "中",          "晚"]
      }
    }
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_02

string

 "string": {  "title": "字符串",  "type": "string",  "maxLength": 4,  "ui:options": {"placeholder": "试着输入超过4个字符"
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_03

color-picker

 "color": {  "title": "颜色选择",  "type": "string",  "format": "color"}复制代码

Vue 3.x Form render_Vue 3.x Form render_04

date-picker

 "date": {  "title": "日期选择",  "type": "string",  "format": "date"}复制代码

Vue 3.x Form render_Vue 3.x Form render_05

image

"image": {  "title": "图片展示",  "type": "string",  "format": "image"}复制代码

Vue 3.x Form render_Vue 3.x Form render_06

number

"allNumber": {  "title": "number类",  "type": "object",  "properties": {"number1": {      "title": "数字输入框",      "description": "1 - 1000",      "type": "number",      "min": 1,      "max": 1000},"number2": {      "title": "带滑动条",      "type": "number",      "ui:widget": "slider"}
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_07

boolean

"allBoolean": {  "title": "boolean类",  "type": "object",  "properties": {"radio": {      "title": "是否通过",      "type": "boolean"},"switch": {      "title": "开关控制",      "type": "boolean",      "ui:widget": "switch"}
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_08

date-range

 "allRange": {  "title": "range类",  "type": "object",  "properties": {"dateRange": {      "title": "日期范围",      "type": "range",      "format": "dateTime",      "ui:options": {"placeholder": [          "开始时间",          "结束时间"]
      }
    }
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_09

emun

 "allEnum": {  "title": "选择类",  "type": "object",  "properties": {"select": {      "title": "单选",      "type": "string",      "enum": ["a","b","c"  ],      "enumNames": ["早","中","晚"  ]
    },"radio": {      "title": "单选",      "type": "string",      "enum": ["a","b","c"  ],      "enumNames": ["早","中","晚"  ],      "ui:widget": "radio"},"multiSelect": {      "title": "多选",      "description": "下拉多选",      "type": "array",      "items": {"type": "string"  },      "enum": ["A","B","C","D"  ],      "enumNames": ["杭州","武汉","湖州","贵阳"  ],      "ui:widget": "multiSelect"},"boxes": {      "title": "多选",      "description": "checkbox",      "type": "array",      "items": {"type": "string"  },      "enum": ["A","B","C","D"  ],      "enumNames": ["杭州","武汉","湖州","贵阳"  ]
    }
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_10

Object

"obj1": {  "title": "可折叠对象",  "description": "这是个对象类型",  "type": "object",  "ui:options": {"collapsed": true
  },  "properties": {"input1": {      "title": "输入框1",      "type": "string"},"input2": {      "title": "输入框2",      "type": "string"}
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_11

rich-text

{  "type": "object",  "properties": {"content": {      "title": "富文本编辑器",      "type": "string",      "format": "richText"}
  }
}复制代码

Vue 3.x Form render_Vue 3.x Form render_12

快速使用

依赖ant-design-vue

import { createApp } from 'vue'import App from './App.vue'import Antd from 'ant-design-vue';import 'ant-design-vue/dist/antd.css';const app = createApp(App);
app.use(Antd);
app.mount('#app');复制代码

引入vue-form-render

npm i kaer-form-render --save复制代码
<template>
  <div><formRender  :schema="schema"  :formData="formData"  @on-change="change"  @on-validate="validate"/>
  </div></template><script>import {reactive, toRefs} from 'vue';// render indeximport FormRender from 'kaer-form-render';// form render styleimport 'kaer-form-render/lib/kaer-form-render.css';export default {  name: 'App',  setup() {const state = reactive({      schema: {type: 'object',properties: {          string: {title: 'string',type: 'string',maxLength: 4,'ui:options': {              placeholder: 'enter more than 4 characters',
            },
          }
        },
      },      formData: {string: 'aaa'  },
    });const change = (v) => {
      state.formData = v;      console.log(v);
    }const validate = (v) => {      console.log(v);
    }return {
      ...toRefs(state),
      change,
      validate,
    }
  },  components: {
    FormRender,
  }
}</script>复制代码

API

Props

参数说明类型默认值
schameJSON Schemaobject--
formData表单的数据object--

Events

事件名说明回调函数
on-change用户触发表单更新的回调函数function(value: formData)
on-validate用户触发表单更新的校验回调函数function(value: validates)

最后

欢迎大家使用并pr,我们一起打造一款好用的vue form render

github: vue form render

在线演示