面向数据编程
面向数据编程是什么样的体验?
其实是数据驱动式编程更向前走一步,我们知道现在MVVM框架,像React、vue、Angular这些给前端带来了很大的进步,更优雅的工程化体系结构,更健壮的代码体系结构。同样给开发者带来了数据驱动式开发的体验,但是业务代码还是经常会出现业务逻辑与UI表达形式的穿插混合的情况,很难统一。
github: https://github.com/chalecao/c...
感谢star!!!
样式行为分离
面向数据的编程其实核心思想还是做样式行为分离,中间的解耦利器便是数据。
样式 mix 行为 = 样式 + 数据 + 行为
于是我们抽象出来的config-component组件,作为驱动样式行为分离的通用组件,驱动面向数据编程。
例如实现下面的表单:
基于antd组件库,比较下不同的代码结构:
左边的图是基于ANTD正常的写法,我们要写Form,要写检验规则,要写子组件等等,关键是这些逻辑是糅合在一起的。右边是基于config-component提供的ConfigForm组件做了封装,只需要提供JSON schema配置数据即可驱动你的页面,分离数据校验和UI逻辑,UI逻辑基于UIconfig,数据校验基于schema做校验。
creative feature创新特性
✅ change your code style to face data, use JSON schema config to driven you page.数据驱动式开发更进一步转向面向数据编程,结合React Hooks开发更高效,专注于数据和业务逻辑.基于JSON配置数据驱动你的页面或者表单。✅ add schema mechanism to ensure you data correct and force you to care you data and handle the abnormal situation.开发中引入schema机制验证核心数据的正确性,无论是表单还是前台组件均可适用。
✅ support get data async, verify data when it changes.基于schema动态校验数据,支持异步数据更新,响应式做校验。
usage用法
安装:
npm install config-component --save
config-component默认提供了2中类型组件,
- ConfigComponent, 通用类型组件,配置页面逻辑,用于前台页面
- ConfigForm, 专用于配置化表单,可以用中后台页面
For common component:
import {ConfigComponent} from 'config-component'
...
<ConfigComponent
initialValues={...}
schema={...}
uiConfig={...}
/>
For form component:
import {ConfigForm} from 'config-component'
...
<ConfigComponent
initialValues={...}
schema={...}
uiConfig={...}
onSubmit={()=>{...}}
componentSet={...}
/>
params:
ℹ️schema: the core data you care, ConfigComponent will verify you core data with schema,you can specify alt props in item, when error occurs, will show alt as default valueℹ️initialValues: init value in you comp
ℹ️uiConfig: define your ui interface with json config, support event hooks, see example in playground file.
ℹ️onSubmit: used only in form when submit data.
ℹ️componentSet: support Ant Design or Fusion or you selfdefine Components.
代码示例:
import React, { useContext } from 'react'
import * as yup from 'yup'
import * as AntdComponents from 'antd'
import moment from 'moment'
import { ConfigForm } from 'config-component'
import 'antd/dist/antd.css'
const schema = yup.object().shape({
firstName: yup.string().required(),
lastName: yup.string().required(),
startTime: yup.array().required(),
useTime: yup.array().required().when('startTime', (startTime, schem) => {
return schem.test(
'check-start',
'useTime required',
value => {
return !!value
},
).test(
'check-start',
'useTime start >= startTime start',
value => {
return value && startTime[0].milliseconds(0).valueOf() <= value[0].milliseconds(0).valueOf()
},
).test(
'check-end',
'useTime end >= startTime end',
value => {
return value && startTime[1].milliseconds(0).valueOf() <= value[1].milliseconds(0).valueOf()
},
).required()
}),
agree: yup.boolean().required().test(
'check-agree',
'agree must checked',
value => {
return !!value
},
).required(),
})
const initialValues = {
firstName: 'Tony',
lastName: 'Stark',
startTime: [moment('2019-09-01'), moment('2019-09-03')],
}
export default function App() {
const formConfig = {
initialValues,
schema,
onSubmit: values => console.log('Your values are:', values),
componentSet: AntdComponents,
}
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
}
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
}
const onChangeWrapper = schemaKey => (form, e) => {
const { onChange, value } = form.getFieldProps(schemaKey)
console.log('prevalue', value)
onChange(e)
}
return (
<ConfigForm
{...formConfig}
uiConfig={{
layout: formItemLayout,
items: [
{
label: 'First Name: ',
comp: 'Input',
schemaKey: 'firstName',
props: {},
},
{
label: 'Last Name: ',
comp: 'Input',
schemaKey: 'lastName',
props: {
onChange: onChangeWrapper('lastName'),
},
},
{
label: 'Start Time: ',
comp: 'DatePicker.RangePicker',
schemaKey: 'startTime',
props: {},
},
{
label: 'Use Time: ',
comp: 'DatePicker.RangePicker',
schemaKey: 'useTime',
props: {},
},
{
layout: tailFormItemLayout,
comp: [
{
comp: 'Checkbox',
schemaKey: 'agree',
props: {
color: '#999',
},
},
{
comp: 'span',
children: '同意协议',
props: {
style: {
marginLeft: '10px',
color: '#999',
},
},
},
],
props: {},
},
{
type: 'submit',
layout: tailFormItemLayout,
comp: [
{
type: 'submit',
comp: 'Button',
children: '提交',
props: {
type: 'primary',
htmlType: 'submit',
key: 'submit',
},
},
{
type: 'reset',
comp: 'Button',
children: '重置',
props: {
type: 'primary',
key: 'reset',
style: { marginLeft: '10px' },
},
},
],
props: {},
},
],
}}
/>
)
}
online example在线案例
playground:https://chalecao.github.io/co...
example - configForm
online example: https://codesandbox.io/s/conf...
example - configComponent
online example: https://codesandbox.io/s/conf...
总结
面向数据的编程,核心关注数据
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。