From 88b4daaca80e43740608fb76e42a2188208e593e Mon Sep 17 00:00:00 2001 From: Jiaqi Liu Date: Tue, 28 Aug 2018 11:43:50 +0800 Subject: [PATCH] =?UTF-8?q?EasyField=20support=20=E2=80=98psssUtil?= =?UTF-8?q?=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 119 +++++++++++++++++++++++------------------ lib/EasyField/index.js | 19 ++++--- package.json | 2 +- 3 files changed, 79 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index fcabd12..4bb5f25 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Happy to build the forms in React ^\_^ * [`select`](#select) * [`checkbox/radio`](#checkboxradio) * [`checkbox/radio group`](#checkboxradio-group) - + [`children | render | compnent`](#children--render--compnent) + + [`children | render | component`](#children--render--component) * [`native form widgets`](#native-form-widgets) * [`custom component`](#custom-component) + [`name`](#name-1) @@ -60,6 +60,7 @@ Happy to build the forms in React ^\_^ + [`validMessage`](#validmessage) + [`checked / unchecked`](#checked--unchecked) + [`valuePropName` `changePropName` `focusPropName` `blurPropName`](#valuepropname-changepropname-focuspropname-blurpropname) + + [`passUtil`](#passutil) - [`
`](#form-) + [`render` | `component`](#render--component) + [`$defaultValues`](#defaultvalues) @@ -122,12 +123,12 @@ yarn add react-formutil `react-formutil` 主要提供了一个 Field 组件和一个 Form 组件,另外还有几个基于此的高阶组件: -* `Field` 组件主要用来负责和具体的表单控件做状态的同步,并向顶层的 `Form` 注册自身。虽然它是一个标准的 react 组件,但是可以把它理解成单个表单控件的 Provider。 -* `Form` 组件通过 `context` 提供了一些方法给 `Field` 组件,并且它增强了传递过来的子组件,向其传递了整个表单的状态。Form 可以理解为整个表单页面的 Provider。 -* `withField` 是基于 `Field` 包装成高阶组件,方便习惯高阶方式的调用 -* `withForm` 是基于 `Form` 包装成高阶组件,方便习惯高阶方式的调用 -* `EasyField` 是基于 `Field` 进行的组件封装,方便直接调用浏览器原生控件去生成表单(可以参考 demo 中的例子) -* `connect` 是个高阶组件,用来给被包装的组件传递`$formutil` 对象,以供调用,返回的新组件必须位于某个 Form 组件的孙子辈才可以拿到`$formutil` +- `Field` 组件主要用来负责和具体的表单控件做状态的同步,并向顶层的 `Form` 注册自身。虽然它是一个标准的 react 组件,但是可以把它理解成单个表单控件的 Provider。 +- `Form` 组件通过 `context` 提供了一些方法给 `Field` 组件,并且它增强了传递过来的子组件,向其传递了整个表单的状态。Form 可以理解为整个表单页面的 Provider。 +- `withField` 是基于 `Field` 包装成高阶组件,方便习惯高阶方式的调用 +- `withForm` 是基于 `Form` 包装成高阶组件,方便习惯高阶方式的调用 +- `EasyField` 是基于 `Field` 进行的组件封装,方便直接调用浏览器原生控件去生成表单(可以参考 demo 中的例子) +- `connect` 是个高阶组件,用来给被包装的组件传递`$formutil` 对象,以供调用,返回的新组件必须位于某个 Form 组件的孙子辈才可以拿到`$formutil` `react-formutil` 不像很多你能看到的其它的 react 表单库,它是非侵入性的。即它并不要求、也并不会强制渲染某种固定的 dom 结构。它只需要提供 `name` 值以及绑定好 `$render` 用来更新输入值,然后一切就会自动同步、更新。 @@ -196,10 +197,10 @@ yarn add react-formutil 该项必填,`name` 可以是一个简单的字符串,也可以是一个字符串表达式(该表达式执行没有 `scope`, 所以表达式中不能存在变量) -* `` -* `` -* `` -* `` +- `` +- `` +- `` +- `` 以上都是合法的 `name` 值。对于多层级的 `name` 值,生成的表单参数对象,也会基于该对象层级创建。例如,上面的示例,将会生成以下格式的表单参数对象: @@ -214,8 +215,8 @@ yarn add react-formutil 该属性可以设置表单控件的默认值/初始值。如过不传递该参数,则默认值都为空字符串。通过该属性,你可以指定某个表单控件的默认值或初始值。 -* `` -* `` +- `` +- `` `$defaultValue` 可以是任意类型值。 @@ -242,9 +243,9 @@ yarn add react-formutil 校验被调用,会传入三个值:value、attr、props -* `value` 为当前 Field 的值 -* `attr` 为校验标识值 -* `props` 为当前传给 Field 的所有 props,还包括当前 Field 所属 Fom 的$formutil +- `value` 为当前 Field 的值 +- `attr` 为校验标识值 +- `props` 为当前传给 Field 的所有 props,还包括当前 Field 所属 Fom 的$formutil ```javascript **需要强调的是,Field 默认不同步`$touched`/`$untouched`、`$focused` 状态,只有`$dirty`/`$pristine`会自动同步(首次调用`$render`会自动同步`$dirty`状态)** > 如果你需要其它状态,需要自己去绑定相关事件来更新状态: @@ -392,14 +393,14 @@ Field 的值实际是保存在状态里的该字段中, Field 的一组状态: -* $dirty 控件被修改过 -* $pristine 控件没有被修改过,与$dirty 互斥 -* $touched 控件失去过焦点 -* $untouched 控件没有失去过焦点 -* $focused 焦点是否在当前控件 -* $pending 是否正在进行异步检查 -* $valid 表单所有控件均校验通过 -* $invalid 表单中有至少一个控件校验不通过 +- $dirty 控件被修改过 +- $pristine 控件没有被修改过,与$dirty 互斥 +- $touched 控件失去过焦点 +- $untouched 控件没有失去过焦点 +- $focused 焦点是否在当前控件 +- $pending 是否正在进行异步检查 +- $valid 表单所有控件均校验通过 +- $invalid 表单中有至少一个控件校验不通过 #### `$error` @@ -498,14 +499,14 @@ export default withField(FieldCustom, { 并且也也内置了一些常用的校验方法,例如: -* `required` 必填,如果是 group.checkbox,则必需至少选中一项 `required` -* `maxLength` 。最大输入长度,支持 group.checkbox。有效输入时才会校验 `maxLength="100"` -* `minLength` 最小输入长度,支持 group.checkbox。有效输入时才会校验 `minLength="10"` -* `max` 最大输入数值,仅支持 Number 比较。有效输入时才会校验 `max="100"` -* `min` 最小输入数值,仅支持 Number 比较。有效输入时才会校验 `min="10"` -* `pattern` 正则匹配。有效输入时才会校验 `pattern={/^\d+$/}` -* `enum` 枚举值检测。有效输入时才会校验 `enum={[1,2,3]}` -* `checker` 自定义校验函数。`checker={value => value > 10 && value < 100 || '输入比如大于10小与100'}` +- `required` 必填,如果是 group.checkbox,则必需至少选中一项 `required` +- `maxLength` 。最大输入长度,支持 group.checkbox。有效输入时才会校验 `maxLength="100"` +- `minLength` 最小输入长度,支持 group.checkbox。有效输入时才会校验 `minLength="10"` +- `max` 最大输入数值,仅支持 Number 比较。有效输入时才会校验 `max="100"` +- `min` 最小输入数值,仅支持 Number 比较。有效输入时才会校验 `min="10"` +- `pattern` 正则匹配。有效输入时才会校验 `pattern={/^\d+$/}` +- `enum` 枚举值检测。有效输入时才会校验 `enum={[1,2,3]}` +- `checker` 自定义校验函数。`checker={value => value > 10 && value < 100 || '输入比如大于10小与100'}` > 注:校验属性的值为 `null` 时表示不进行该校验 @@ -515,16 +516,16 @@ export default withField(FieldCustom, { 当设置了 type 时,EasyField 将会尝试直接渲染浏览器表单元素。它支持以下类型: -* `input[type=text]` -* `input[type=number]` -* `input[type=search]` -* `input[type=password]` -* `input[type=checkbox]` -* `input[type=radio]` -* `select` -* `textarea` -* `group.radio` -* `group.checkbox` +- `input[type=text]` +- `input[type=number]` +- `input[type=search]` +- `input[type=password]` +- `input[type=checkbox]` +- `input[type=radio]` +- `select` +- `textarea` +- `group.radio` +- `group.checkbox` > EasyField 对亚洲语言(中文、韩文、日文)输入法在输入过程中的的字母合成做了处理 @@ -582,7 +583,7 @@ export default withField(FieldCustom, { ``` -#### `children | render | compnent` +#### `children | render | component` 当 type 属性没有指定时,会根据这三个属性来进行渲染,并且将 EasyField 定义的同步回调方法(`onChange` `onFocus` `onBlur`)和当前值(`value`)传递下去。 @@ -716,15 +717,27 @@ function MyComponent({ current, onUpdate }) { ; ``` +#### `passUtil` + +但使用自定义组件时,如果需要访问当前 Field 的状态,可以通过设置该参数,传入一个字符串,EasyField 会将状态通过该参数值传递给自定义组件: + +```javascript + + {({ $fieldutil, onChange, value }) => { + return ; + }} + +``` + ### `` `Form` 也是一个标准的 react 组件,它类似 Field,同样可以以函数、或者普通组件当作子组件调用。它可以增强子组件,收集子 dom 树中的 `Field` 组件状态,并通过$formutil 传递给被调用组件。 经过 `Form` 增强的组件,会在其 `props` 中接收到一个`$formutil`对象。例如 -* 你可以通过`$formutil.$params` 拿到整个表单的输入值 -* 你可以通过`$formutil.$invalid` 或 `$formutil.$valid` 来判断表单是否有误 -* 你可以通过`$formutil.$errors` 来获取表单的错误输入信息 +- 你可以通过`$formutil.$params` 拿到整个表单的输入值 +- 你可以通过`$formutil.$invalid` 或 `$formutil.$valid` 来判断表单是否有误 +- 你可以通过`$formutil.$errors` 来获取表单的错误输入信息 `Form` 可以接收以下可选属性参数: @@ -1204,9 +1217,9 @@ import { findDOMNode } from 'react-dom'; 比如同时要收集用户的个人信息和工作信息,我们可以将其拆分为三个模块: -* `Userinfo.js` 用户基本信心的字段 -* `Workinfo.js` 用户工作信息的字段 -* `Submit.js` 提交区域(因为只有在 Form 组件下级才能拿到$formutil 信息) +- `Userinfo.js` 用户基本信心的字段 +- `Workinfo.js` 用户工作信息的字段 +- `Submit.js` 提交区域(因为只有在 Form 组件下级才能拿到$formutil 信息) 注: Submit.js 和 Workinfo.js 合并到一起也是可以的。 @@ -1386,7 +1399,7 @@ class MyForm extends Component { 是的,可以直接使用`EasyField`嵌套 `antd` 的组件即可。唯一需要注意的是,由于`react-formutil`默认所有的人表单域的值为空字符串,所以和`antd`一起使用时,部分组件由于不接收字符串值,所以需要设置`$defaultValue={undefined}`。 -另外我们也提供了一个独立的组件专门用于antd项目,它使用了``来对表单校验状态等做了同步,并且调用起来更加简洁:[`react-antd-formutil`](https://github.com/qiqiboy/react-antd-formutil) +另外我们也提供了一个独立的组件专门用于 antd 项目,它使用了``来对表单校验状态等做了同步,并且调用起来更加简洁:[`react-antd-formutil`](https://github.com/qiqiboy/react-antd-formutil) [![npm](https://img.shields.io/npm/v/react-antd-formutil.svg?style=flat)](https://npm.im/react-antd-formutil) diff --git a/lib/EasyField/index.js b/lib/EasyField/index.js index 67a0e7e..58e881e 100644 --- a/lib/EasyField/index.js +++ b/lib/EasyField/index.js @@ -101,8 +101,9 @@ var EasyField = (_temp = _class = function (_Component) { $validators = fieldProps.$validators, $asyncValidators = fieldProps.$asyncValidators, validMessage = fieldProps.validMessage, + passUtil = fieldProps.passUtil, __TYPE__ = fieldProps.__TYPE__, - otherProps = _objectWithoutProperties(fieldProps, ['$defaultValue', '$defaultState', '$onFieldChange', '$validators', '$asyncValidators', 'validMessage', '__TYPE__']); + otherProps = _objectWithoutProperties(fieldProps, ['$defaultValue', '$defaultState', '$onFieldChange', '$validators', '$asyncValidators', 'validMessage', 'passUtil', '__TYPE__']); var children = fieldProps.children; @@ -210,22 +211,24 @@ var EasyField = (_temp = _class = function (_Component) { onBlur && onBlur(ev); }), _Object$assign)); - var childPropsUtil = Object.assign({}, childProps, { $fieldutil: $util }); + if (passUtil) { + childProps[passUtil] = $util; + } if (TheComponent) { - return React.createElement(TheComponent, childPropsUtil); + return React.createElement(TheComponent, childProps); } if (isFunction(render)) { - return render(childPropsUtil); + return render(childProps); } if (isFunction(children)) { - return children(childPropsUtil); + return children(childProps); } return Children.map(children, function (child) { - return cloneElement(child, child && isFunction(child.type) ? childPropsUtil : childProps); + return cloneElement(child, childProps); }); } ); @@ -261,7 +264,9 @@ var EasyField = (_temp = _class = function (_Component) { blurPropName: PropTypes.string, $parser: PropTypes.func, - $formatter: PropTypes.func + $formatter: PropTypes.func, + + passUtil: PropTypes.string }, _class.defaultProps = { validMessage: {}, valuePropName: 'value', diff --git a/package.json b/package.json index aeffaf8..5fc3ff4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-formutil", - "version": "0.3.1", + "version": "0.3.2", "description": "Happy to build the forms in React ^_^", "main": "lib/index.js", "directories": {