Vue前端表单解决方案VSchemaForm

在前端开发的工作当中,表单的开发占据了很大的一部分。表单页面和报表页面是中后台业务的主要展现形式,但随着业务越来越复杂,表单开发和维护成为了前端工程师一个无法逃避的痛点。

目前的表单开发主要存在的问题有以下几点

  1. 表单状态管理随业务复杂度增加变得越来越难以维护,需要引入状态管理库
  2. 传统表单开发的数据结构往往都是扁平结构,没法很好的处理嵌套复杂数据的情况, 如果要处理,工作量会非常大
  3. 当业务有动态输出表单的需求的时候,不得不自己开发一个基于某种数据协议的动态输出表单的组件
  4. 当业务需要在可视化界面配置产出表单时,需要自己开发一个基于json的动态输出表单组件

解决方案

基于以上问题的探索,以及受到UForm的启发,研发了VSchemaForm的Vue表单解决方案:

  1. 使用json描述表单内容
  2. 支持多平台(移动端和桌面端)
  3. 支持多个组件库(Element UI、Ant Design Vue、Antd Mobile Vue)
  4. 支持嵌套表单
  5. 支持任意数据的数组解构
  6. 支持复杂布局
  7. 支持副作用函数,统一处理表单内各项的数据联动
  8. 支持解构数据,减少自定义的数据转换
  9. 支持表单校验

这是一个完整的表单解决方案,并且不和任何第三方库绑定,项目文档地址项目主页,github地址为github.com/wuhao000/vu…

使用JSON描述表单

{

fields: {

card: {

type: 'card',

props: {

title: '基本信息'

},

fields: {

basic: {

type: 'object',

fields: {

str: {

type: 'string',

title: '字段1'

},

num: {

type: 'number',

title: '字段2'

},

date: {

type: 'date',

title: '字段3'

}

}

}

}

},

detailCard: {

type: 'card',

props: {

'title': '详细信息'

},

fields: {

detail: {

type: 'object',

props: {

labelCol: 8,

wrapperCol: 12

},

fields: {

gridLayout: {

type: 'grid',

layout: [6, 11],

props: {

gutter: 10,

title: '字段3'

},

fields: {

field3Num: {type: 'number'},

field3Date: {'type': 'date'}

}

},

gridLayout2: {

type: 'grid',

layout: [6, 16],

props: {gutter: 10, title: '对象字段'},

fields: {

objNum: {type: 'number'},

'[startDate,endDate]': {type: 'daterange'}

}

},

textbox: {

type: 'text-box',

title: '文本串联',

layout: '订%s元/票 退%s元/票 改%s元/票',

fields: {

text1: {

type: 'number',

default: 10,

required: true

},

text2: {

type: 'number',

default: 20,

required: true

},

text3: {

type: 'number',

default: 30,

required: true

}

}

},

field4: {

type: 'string',

title: '字段4'

},

section: {

type: 'object',

props: {

title: '区块'

},

fields: {

field5: {

type: 'string',

title: '字段5'

},

field6: {

type: 'string',

title: '字段6'

}

}

}

}

}

}

}

}

}

这是一个比较复杂的表单的布局示例,布局效果如下:

多平台支持

桌面端和移动端只要指定platform属性(mobile或desktop),这对于响应式的系统来说,只需要一个属性就能达到响应式布局的效果。

副作用处理

表单副作用,也就是由表单字段的内部事件所产生的联动,校验,异步逻辑,如何更好的管理和维护副作用逻辑,恰好就是rxjs的最大优势,所以,本方案采用了rxjs来管理副作用逻辑

表单的API中包含的effects即为表单的副作用函数,这个effects是一个功能极为强大的回调函数, 它接收了一个selector函数作为参数,我们可以用selector来选择表单内的任意一个或多个字段, 对其做状态修改,即便存在异步逻辑,也是可以很方便的在各种异步环境下对字段的状态做修改, 所以,我们的表单联动,是不限于时空的。

effects示例

const effects = ($: EffectsContext) => {

$('s1').onFieldChange(value => {

$('s2').value(value);

});

$('s1').onFieldChange(value => {

if (value !== '3') {

$('s3', 's4'). hide();

} else {

$('s3', 's4').show();

}

});

}

以上事例代码展示了,在一个表单中有s1,s2,s3,s4四个输入组件,注册了两个事件:

  1. 当s1的值发生变化时,将s1的值复制给s2
  2. 当s1的值发生变化时,如果值等于'3',则显示s3,s4,反之则隐藏

副作用函数还有很多强大功能,不限于:赋值、事件监听、更改属性、隐藏/显示等

字段解构

字段解构是一个非常强大的特性,它可以对组件生产的值做解构转换,使得快速贴合服务端数据结构要求,无需再做二次转换 字段解构主要是对 property 用 ES Deconstruction 语法做解构,需要注意的是,不支持...语法

通常,我们使用日期范围组件的时候组件生产的值是一个数组,但是往往服务端都是以 startDate,endDate 的方式做存储,如果每次前端都花大量精力去转换的话, 其实成本还是很高的。所以,我们可以借助字段解构,轻松解决该问题.

另外,还有如省市区选择等

{

fields: {

'[start, end]': {

type: 'daterange',

title: '时间范围'

},

'[province,city,town]': {

type: 'cascader',

title: '省市区',

placeholder: '请选择',

enum: this.options

}

}

}

以上就是一个使用了解构的表单的schema描述,其中只有两个输入组件,但实际的数据格式是:

{

"start": "2019-11-18T00:15:10.495Z",

"end": "2019-11-18T00:15:10.495Z",

"province": "jiangsu",

"city": "nj",

"town": "gl"

}

布局支持

线性布局

组合布局

编辑与详情模式切换

可直接切换为详情模式

数据校验

支持数据

支持表单部分自定义

使用slot可以达到部分表单内容使用自定义内容

以上是VSchemaForm的主要功能,其他功能详见项目主页

以上是 Vue前端表单解决方案VSchemaForm 的全部内容, 来源链接: utcz.com/a/33905.html

回到顶部