|
导读网页的本质就是超级文本标记语言,通过结合使用其他的Web技术(如:脚本语言、公共网关接口、组件等),可以创造出功能强大的网页。因而,超级文本标记语言是万维网(Web)编程的基础,也就是说万维网是建立... 网页的本质就是超级文本标记语言,通过结合使用其他的Web技术(如:脚本语言、公共网关接口、组件等),可以创造出功能强大的网页。因而,超级文本标记语言是万维网(Web)编程的基础,也就是说万维网是建立在超文本基础之上的。超级文本标记语言之所以称为超文本标记语言,是因为文本中包含了所谓“超级链接”点。 本篇文章给大家带来的内容是关于JSON生成Form表单的详细解析(代码实例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。JSON表单 描述 JSON表单是一个基于React的抽象组件,它可以把JSON数据格式描述的表单转换成项目中的表单,它可以用简短的几行代码,快速的生成Form表单。
原始表单的缺点1:代码量庞大,开发效率低 2:不便于抽离和进一步的抽象 3:维护成本高 4:需要额外处理校验和缓存等功能 一个栗子const config = {
formKey: 'example-form',
data: {
name: '',
descr: '',
typeName: ''
},
config: [
{
type: 'input',
dataKey: 'name',
label: 'param',
placeholder: '请输入param',
validate: ['required', /^[a-zA-Z_{}0-9]+$/g],
style: {
display: 'inline-block',
width: 270,
},
},
{
type: 'select',
dataKey: 'typeName',
options: ['string', 'integer', 'float'],
style: {
display: 'inline-block',
width: 100,
margin: '0 15px'
},
validate: [{type: 'required', message: 'param类型不能为空'}]
},
{
type: 'textarea',
dataKey: 'descr',
placeholder: '请输入param含义',
label: 'param含义',
validate: ['required'],
style: {
width: 385,
}
},
]
}
<From ref={ref => this.FormWrap = ref} config={config}></From>上面是用JSON描述的三个常用的表单组件组合成的表单,其效果图如下:
JSON表单的格式{
formKey: 'paramAddForm',
data: {},
config: []
}
表单组件的配置{
type: 'input',
dataKey: 'name',
label: 'param',
validate: ['required'],
style: {}
}
关键字段解释1. typetype是用来唯一表示表单组件类型的字段,其中JSON表单提供了三种默认的表单组件:input、select、textarea,还有两种复杂类型的表单组件:form_array、container。 form_array表单组件表示其数据结构为Array,含有增加项删除项的复合表单组件,该表单组件的配置里多一个children的字段,里面是每一项里面的表单组件配置的集合,其表单组件的效果如下图所示:
container是用来自定义表单的接口,具体用法参考下面具体的介绍。 2. validatevalidate是校验表单组件数据正确性的字段,其值为数组,里面的数组元素可以为String、object、RegExp、Function。 JSON表单采用的是 1. 数组元素为string,其值可以为:
string,值必须为string
number,值必须为数字
required,值不能为空
boolean,值必须为布尔值
integer,值必须为整数形
float,值必须为浮点型
email,值必须为邮箱类型
2. 数组元素为object,其值为rules:
{type: 'enum', enum: ['1', '2'], message: '值不在确定范围内'}
3. 数组元素为RegExp, validate: [/^[a-zA-Z_{}0-9]+$/g]
4. 数组元素为Function, validate: [ (rules, value, callback) => {}]3. style用来确定表单组件在表单内的布局样式,比如想让表单组件行内显示,且宽度为200,其style值如下: {
display: 'inline-block',
width: 200
}container表单组件container表单组件是用来自定义表单组件的,它主要的作用有以下几点:
使用栗子import { Input, Select } from 'antd'
const Option = Select.Option
{
type: 'container',
dataKey: 'descr',
style: {
display: 'inline-block',
width: 100,
margin: '0 15px'
},
options: ['string', 'integer', 'float'],
render: (curData, config, {changeFn, getFocus, loseFocus, error}) => {
return <Select value={curData}
style={{width: '100%', height: 35}}
onMouseEnter={getFocus}
onChange={(value) => changeFn(value, () => {
loseFocus()
})}>
{
config.options && config.options.map((item, idx) => <Option key={idx} value={item}>{item}</Option>)
}
</Select>
}
},container表单组件只是多一个render渲染方法,里面可以自定义表单组件的渲染内容,render方法提供如下参数: 1. curData: 当前container组件的值,跟dataKey相关 使用antd的组件库JOSN表单只提供了input、select、textarea三种默认的表单组件,远远不够真实的项目中使用,所以我们可以将antd组件库中的组件封装到JSON表单中,这样我们就可以再项目中很快的使用antd中的组件。 antd-components.js import React from 'react'
import { Input } from 'antd'
export default [
{
type: 'antd-input',
render: (curData, config, {changeFn, getFocus, loseFocus, error}) => {
return <Input value={curData}
onFocus={getFocus}
onBlur={loseFocus}
placeholder={config.placeholder ? config.placeholder : ''}
style={{borderColor: !!error ? '#f5222d' : ''}}
onChange={event => changeFn(event.target.value)} />
}
}
]我们在antd-components.js文件中声明一个 init.js import Form from 'Form'
import components from './antd-components'
From.createCustomComp(components)
const config = {
formKey: 'paramAddFromAntd',
data: {
name: '',
},
config: [
{
type: 'antd-input',
dataKey: 'name',
label: 'Param',
placeholder: '请输入param',
validate: ['required', /^[a-zA-Z_{}0-9]+$/g]
}
]
}
<From ref={ref => this.FormWrap = ref} config={config}></From>使用container来引入antd组件库,其原理就是通过container将antd组件封装成'antd-input'自定义组件,然后使用它,这种方式不仅可以用来封装组件库,还可以用来共享一些共用表单组件,可以将常用的复杂表单组件封装在一个共用文件里,然后在不同项目中引用,就可以跨项目共用表单组件。 在自定义组件中,如果需要自定义表单提交数据函数,但是又不能重写render方法以防覆盖原先的render方法,所以可以使用modifyDataFn方法来覆盖render中的提交数据部分。 modifyDataFn: ({changeFn, changeDataFn}, {parent, self}) => {
let {parentData} = parent
parentData = parentData.map(item => ({
...item,
name: self.curData
}))
changeDataFn(parent.parentKey, parentData)
}处理控制逻辑和联动逻辑在JSON表单JSON配置中,有assistData的选填字段,该字段为JSON表单处理控制逻辑的额外数据,例如在表单内有一个刷新按钮,其实现代码如下: {
data: {},
assistData: {
refreshParam: false
},
config: [
{
type: 'container',
dataKey: 'assistData.refreshParam',
render: (curData, config, {changeFn, changeDataFn}) => {
const handleClick = () => {
changeDataFn('assistData.refreshParam' ,true)
setTimeout(() => {
changeDataFn('assistData.refreshParam' ,false)
}, 1000 * 3)
}
return <React.Fragment>
{
config.index === config.parentData.length - 1 &&
<Popover placement="top" content="刷新param列表">
<Button shape="circle" loading={curData} onClick={handleClick}>{!curData && <Icon type="reload" />}</Button>
</Popover>
}
</React.Fragment>
}
},
]
}注意: 如果要使用assistData中的数据,其dataKey必须以 render方法内嵌套组件配置{
type: 'container',
dataKey: 'param',
render: (curData, config, {changeFn, changeDataFn, JSONForm}) => {
return <p>
{
JSONForm([
{
type: 'input',
dataKey: 'name',
placeholder: '请输入param',
validate: ['required'],
}
])
}
</p>
}这样就可以在container内嵌套组件配置,实现更复杂的表单组件。 JSON表单提交数据非实时表单提交非实时表单提交数据,就是在表单输入完毕后,点击提交按钮统一提交所有的数据,其提交的方式如下: function handleClick() {
this.FormRefs.getValue((valid, data) => {
// valid 表示校验结果,false表示校验不通过
})
}实时表单提交实时表单的提交首先需要注册提交函数: componentDidMount(){
this.FormRefs.registerSubmit((valid, data) => {
console.log(valid, data)
})
}接着在配置里设置允许实时提交的字段: {
formKey: '',
realTimeSubmit: true
}如果需要在某些表单组件里自定义是否实时提交,需要在组件配置里设置阻止实时提交字段为true: {
dataKey: '',
preventSubmit: true
}JSON表单的应用场景表单分类a. 按复杂度分类 JSON表单最适合的应用场景是简单表单,它可以用极少的代码,快速的构建出表单来,对于复杂类型的表单,JSON表单需要使用container来构建复杂的表单组件、处理复杂的控制逻辑,其代码量优势虽然并不明显,但是JSON表单可以使其代码清晰,将表单组件和表单逻辑彻底解耦,便于抽离和维护,便于共享常用组件,也带来不少的好处。 到目前为止,JSON表单适合大部分的表单应用场景。 JSON表单解决的问题
在我的项目,我尝试了使用原始表单和JSON表单两种方式来实现同一个表单页,原始表单我编写了600多行的代码,而在JSON表单中,只有不到150行。 以上就是JSON生成Form表单的详细解析(代码实例)的详细内容,更多请关注php中文网其它相关文章! 网站建设是一个广义的术语,涵盖了许多不同的技能和学科中所使用的生产和维护的网站。 |
温馨提示:喜欢本站的话,请收藏一下本站!