forked from ascoders/weekly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
151 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
组件值校验,即在组件值变化时判断是否满足校验逻辑,若不满足校验逻辑,可以拿到校验错误信息进行错误提示或其他逻辑处理。 | ||
|
||
声明 `valueValidator` 可开启值校验: | ||
|
||
```js | ||
import { ComponentMeta } from "designer"; | ||
|
||
const input: ComponentMeta = { | ||
componentName: "input", | ||
element: Input, | ||
valueValidator: () => ({ | ||
required: true, | ||
maximum: 10, | ||
}), | ||
}; | ||
``` | ||
|
||
如上面的例子,相当于对组件值做了 “不能为 `undefined` 且最大值为 10” 的限制。 | ||
|
||
- 可以内置 [JSONSchema validate](https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6) 的全部校验规则作为内置规则。 | ||
- 支持拓展自定义校验规则。 | ||
- 支持异步校验。 | ||
- 可以用 selector 绑定任意变量(如全局状态 `state` 或者当前组件实例的 `props` 来灵活定义组件值校验规则)。 | ||
|
||
当校验出错时,框架也不会做任何处理,而是将错误抛给业务,由业务来判断如何处理错误。 | ||
|
||
接下来我们来详细说说每一项特征。 | ||
|
||
## 错误处理 | ||
|
||
定义了组件值校验后,当校验错误出现时,可以通过 `selector` 的 `validateError` 拿到错误信息: | ||
|
||
```js | ||
const input: ComponentMeta = { | ||
componentName: "input", | ||
element: Input, | ||
valueValidator: () => ({ | ||
required: true, | ||
maximum: 10, | ||
}), | ||
runtimeProps: ({ selector }) => ({ | ||
errorName: selector(({ validateError }) => validateError.ruleName), | ||
errorMessage: selector(({ validateError }) => validateError.payload), | ||
}), | ||
}; | ||
``` | ||
|
||
- `ruleName`: 校验规则名称。 | ||
- `payload`: 该规则未命中时的返回值,校验函数返回什么,这里拿到的就是什么。内置的校验函数返回的是错误信息文案。 | ||
|
||
拿到校验错误后,通过 `runtimeProps` 传给组件,我们可通过组件自身或 `element` 增加统一的组件 React 容器层处理并展示这些错误信息。 | ||
|
||
也可以使用 `fetcher` 接收这个错误,并调整取数参数。总之支持 `selector` 的地方都可以响应校验错误,如何使用完全由你决定。 | ||
|
||
## 自定义校验规则 | ||
|
||
`createDesigner` 传递的中间件可以拓展自定义校验规则: | ||
|
||
```js | ||
import { createMiddleware } from "designer"; | ||
const myMiddleware = createMiddleware({ | ||
validateRules: { | ||
// 自定义校验规则,判断是否为空字符串 | ||
isEmptyString: (value, options?: { errorMessage?: string }) => { | ||
if (value === "") { | ||
return true; | ||
} | ||
return options.errorMessage; | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
通过 `validateRules` 定义自定义校验规则后,就可以在 `valueValidator` 中使用了: | ||
|
||
```js | ||
const input: ComponentMeta = { | ||
componentName: "input", | ||
element: Input, | ||
valueValidator: () => ({ | ||
isEmptyString: { | ||
errorMessage: "字符串必须为空", | ||
}, | ||
}), | ||
}; | ||
``` | ||
|
||
## 用 selector 绑定校验规则 | ||
|
||
利用 `selector` 将校验规则绑定到任意状态,比如: | ||
|
||
```js | ||
const input: ComponentMeta = { | ||
componentName: "input", | ||
element: Input, | ||
valueValidator: ({ selector }) => selector(({ props }) => props.validator), | ||
}; | ||
``` | ||
|
||
上面的例子,将所有组件名为 `input` 组件的校验规则绑定到当前组件实例的 `props.validator` 上。 | ||
|
||
```js | ||
const input: ComponentMeta = { | ||
componentName: "input", | ||
element: Input, | ||
valueValidator: ({ selector }) => | ||
selector(({ state }) => state.validatorInfo), | ||
}; | ||
``` | ||
|
||
上面的例子,将所有组件名为 `input` 组件的校验规则绑定绑定到全局状态 `state.validatorInfo` 上。 | ||
|
||
## 异步校验 | ||
|
||
将自定义校验函数定义为异步函数,就可以定义异步校验。 | ||
|
||
```js | ||
const myMiddleware = createMiddleware({ | ||
validateRules: { | ||
isEmptyString: async (value, options?: { errorMessage?: string }) => { | ||
await wait(1000); | ||
if (value === "") { | ||
return true; | ||
} | ||
return options.errorMessage; | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
如上所示,定义了 `isEmptyString` 的错误校验规则,那么当校验函数执行完后,在 1s 后将会出现校验信息。 | ||
|
||
## 总结 | ||
|
||
组件值校验依然提供了强大的灵活拓展性,以下几种定制能力相互正交,将灵活性成倍放大: | ||
|
||
1. `valueValidator` 利用 `selector` 绑定任意值,这样既可以定义固定的校验规则,也可以定义跟随全局状态变化的校验规则,也可定义跟随当前组件实例 props 变化的校验规则。 | ||
2. 在此基础上,还可以自定义校验规则,且支持异步校验。 | ||
3. 更精彩的是,对值校验失败时,如何处理校验失败的表现交给了业务层。我们再次依托强大的 `selector` 设计,将校验错误传给 `selector`,就让校验错误的用法产生了无限可能。比如用在 `runtimeProps` 可以让渲染响应校验错误,用在 `fetcher` 可以让查询响应校验错误。 | ||
|
||
> 讨论地址是:[精读《组件值校验》· Issue #473 · dt-fe/weekly](https://github.com/dt-fe/weekly/issues/473) | ||
**如果你想参与讨论,请 [点击这里](https://github.com/dt-fe/weekly),每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。** | ||
|
||
> 关注 **前端精读微信公众号** | ||
<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg"> | ||
|
||
> 版权声明:自由转载-非商用-非衍生-保持署名([创意共享 3.0 许可证](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)) |