基於config-component轉向面向數據的編程?

面向數據編程

面向數據編程是什麼樣的體驗?

實際上是數據驅動式編程更向前走一步,咱們知道如今MVVM框架,像React、vue、Angular這些給前端帶來了很大的進步,更優雅的工程化體系結構,更健壯的代碼體系結構。一樣給開發者帶來了數據驅動式開發的體驗,可是業務代碼仍是常常會出現業務邏輯與UI表達形式的穿插混合的狀況,很難統一。javascript

github: https://github.com/chalecao/c...
感謝star!!!css

樣式行爲分離

面向數據的編程其實核心思想仍是作樣式行爲分離,中間的解耦利器即是數據。html

樣式 mix 行爲 = 樣式 + 數據 + 行爲

因而咱們抽象出來的config-component組件,做爲驅動樣式行爲分離的通用組件,驅動面向數據編程。前端

例如實現下面的表單:vue

clipboard.png

基於antd組件庫,比較下不一樣的代碼結構:java

clipboard.png

左邊的圖是基於ANTD正常的寫法,咱們要寫Form,要寫檢驗規則,要寫子組件等等,關鍵是這些邏輯是糅合在一塊兒的。右邊是基於config-component提供的ConfigForm組件作了封裝,只須要提供JSON schema配置數據便可驅動你的頁面,分離數據校驗和UI邏輯,UI邏輯基於UIconfig,數據校驗基於schema作校驗。node

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機制驗證核心數據的正確性,不管是表單仍是前臺組件都可適用。react

✅ support get data async, verify data when it changes.基於schema動態校驗數據,支持異步數據更新,響應式作校驗。git

usage用法

安裝:github

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...

總結

面向數據的編程,核心關注數據

參考

fed123前端學堂

相關文章
相關標籤/搜索