Vue前端表单解决方案VSchemaForm
在前端开发的工作当中,表单的开发占据了很大的一部分。表单页面和报表页面是中后台业务的主要展现形式,但随着业务越来越复杂,表单开发和维护成为了前端工程师一个无法逃避的痛点。
目前的表单开发主要存在的问题有以下几点
- 表单状态管理随业务复杂度增加变得越来越难以维护,需要引入状态管理库
- 传统表单开发的数据结构往往都是扁平结构,没法很好的处理嵌套复杂数据的情况, 如果要处理,工作量会非常大
- 当业务有动态输出表单的需求的时候,不得不自己开发一个基于某种数据协议的动态输出表单的组件
- 当业务需要在可视化界面配置产出表单时,需要自己开发一个基于json的动态输出表单组件
解决方案
基于以上问题的探索,以及受到UForm的启发,研发了VSchemaForm的Vue表单解决方案:
- 使用json描述表单内容
- 支持多平台(移动端和桌面端)
- 支持多个组件库(Element UI、Ant Design Vue、Antd Mobile Vue)
- 支持嵌套表单
- 支持任意数据的数组解构
- 支持复杂布局
- 支持副作用函数,统一处理表单内各项的数据联动
- 支持解构数据,减少自定义的数据转换
- 支持表单校验
这是一个完整的表单解决方案,并且不和任何第三方库绑定,项目文档地址项目主页,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四个输入组件,注册了两个事件:
- 当s1的值发生变化时,将s1的值复制给s2
- 当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