From 2e54d32181a74f46ef453c00a9f60449932d66b9 Mon Sep 17 00:00:00 2001 From: liaoxuezhi Date: Wed, 17 Jul 2019 11:04:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/dev.md | 104 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/docs/dev.md b/docs/dev.md index 21ab18dd9..f58c6393b 100644 --- a/docs/dev.md +++ b/docs/dev.md @@ -17,7 +17,7 @@ import * as cx from 'classnames'; @FormItem({ type: 'custom-checkbox', }) -export default class CustomCheckbox extends React.PureComponent { +export default class CustomCheckbox extends React.Component { toggle = () => { const {value, onChange} = this.props; @@ -68,6 +68,45 @@ export default class CustomCheckbox extends React.PureComponent { 至于其他功能如:label/description 的展示、表单验证功能、表单布局(常规、左右或者内联)等等,只要是通过 FormItem 注册进去的都无需自己实现。 +#### 自定义验证器 + +如果 amis [自带的验证](./renderers/Form/FormItem.md#)能满足需求了,则不需要关心。组件可以有自己的验证逻辑。 + +```jsx +import * as React from 'react'; +import {FormItem} from 'amis'; +import * as cx from 'classnames'; + +@FormItem({ + type: 'custom-checkbox', +}) +export default class CustomCheckbox extends React.Component { + validate() { + // 通过 this.props.value 可以知道当前值。 + + return isValid ? '' : '不合法,说明不合法原因。' + } + // ... 其他省略了 +} +``` + +上面的栗子只是简单说明,另外可以做`异步验证`,validate 方法可以返回一个 promise。 + +#### OptionsControl + +如果你的表单组件性质和 amis 的 Select、Checkboxes、List 差不多,用户配置配置 source 可通过 API 拉取选项,你可以用 OptionsControl 取代 FormItem 这个注解。 + +用法是一样,功能方面主要多了以下功能。 + +* 可以配置 options,options 支持配置 visibleOn hiddenOn 等表达式 +* 可以配置 `source` 换成动态拉取 options 的功能,source 中有变量依赖会自动重新拉取。 +* 下发了这些 props,可以更方便选项。 + - `options` 不管是用户配置的静态 options 还是配置 source 拉取的,下发到组件已经是最终的选项了。 + - `selectedOptions` 数组类型,当前用户选中的选项。 + - `loading` 当前选项是否在加载 + - `onToggle` 切换一个选项的值 + - `onToggleAll` 切换所有选项的值,类似于全选。 + ### Renderer 非表单类的组件自定义,主要通过 `Renderer` 实现。在开始阅读之前,请先阅读 [amis 工作原理](./sdk.md#工作原理)。 @@ -103,46 +142,41 @@ class CustomRenderer extends React.Component { 请注意 `this.props` 中的 `render` 方法,它用来实现容器功能,通过它可以让使用者动态的配置其他渲染模型。 -## 工具 +### 组件间通信 -目前主要提供以下工具。 - -### fetch - -```jsx -import {fetch} from 'amis/utils'; -``` - -用来做 ajax 请求。参数说明 - -- `api` 字符串或者 api 对象,如: {url: 'http://www.baidu.com', method: 'get'}, api 地址支持变量。 -- `data` 数据体 - -返回一个 Promise。 - -如: +关于组件间通信,amis 中有个机制就是,把需要被引用的组件设置一个 name 值,然后其他组件就可以通过这个 name 与其通信,比如这个[栗子](./advanced.md#组件间通信)。其实内部是依赖于内部的一个 Scoped Context。你的组件希望可以被别的组件引用,你需要把自己注册进去,默认自定义的非表单类组件并没有把自己注册进去,可以参考以下代码做添加。 ```js -import {fetch} from 'amis/utils'; +import * as React from 'react'; +import {Renderer, ScopedContext} from 'amis'; +@Renderer({ + test: /(?:^|\/)my\-renderer$/, +}) +export class CustomRenderer extends React.Component { + static contextType = ScopedContext; -fetch('http://www.baidu.com/api/xxx?a=${a}&b=${b}', { - a: 'aa', - b: 'bb', -}).then(function(result) { - console.log(result); -}); + componentWillMount() { + const scoped = this.context; + scoped.registerComponent(this); + } + + componentWillUnmount() { + const scoped = this.context; + scoped.unRegisterComponent(this); + } + + // 其他部分省略了。 +} ``` -### filter +把自己注册进去了,其他组件就能引用到了。同时,如果你想找别的组件,也同样是通过 scoped 这个 context,如: `scoped.getComponentByName("xxxName")` 这样就能拿到目标组件的实例了(前提是目标组件已经配置了 name 为 `xxxName`)。 -```jsx -import {filter} from 'amis/utils'; -``` +### 其他功能方法 -主要用来做字符替换,如: +自定义的渲染器 props 会下发一个非常有用的 env 对象。这个 env 有以下功能方法。 -```js -import {filter} from 'amis/utils'; - -filter('blabla?a={a}', {a: 123}); // => 'blabla?a=123' -``` +* `env.fetcher` 可以用来做 ajax 请求如: `this.props.env.fetcher('xxxAPi', this.props.data).then((result) => console.log(result))` +* `env.confirm` 确认框,返回一个 promise 等待用户确认如: `this.props.env.confirm('你确定要这么做?').then((confirmed) => console.log(confirmed))` +* `env.alert` 用 Modal 实现的弹框,个人觉得更美观。 +* `env.notify` toast 某个消息 如: `this.props.env.notify("error", "出错了")` +* `env.jumpTo` 页面跳转。 \ No newline at end of file