Skip to content

Commit feeee26

Browse files
committed
275
1 parent b6ced07 commit feeee26

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

readme.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
前端界的好文精读,每周更新!
88

9-
最新精读:<a href="./可视化搭建/274.%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8%E5%8D%8F%E8%AE%AE.md">274.定义联动协议</a>
9+
最新精读:<a href="./可视化搭建/275.%E7%BB%84%E4%BB%B6%E5%80%BC%E6%A0%A1%E9%AA%8C.md">275.组件值校验</a>
1010

1111
素材来源:[周刊参考池](https://github.com/ascoders/weekly/issues/2)
1212

@@ -308,6 +308,7 @@
308308
- <a href="./可视化搭建/272.%E5%AE%B9%E5%99%A8%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1.md">272.容器组件设计</a>
309309
- <a href="./可视化搭建/273.%E7%BB%84%E4%BB%B6%E5%80%BC%E4%B8%8E%E8%81%94%E5%8A%A8.md">273.组件值与联动</a>
310310
- <a href="./可视化搭建/274.%E5%AE%9A%E4%B9%89%E8%81%94%E5%8A%A8%E5%8D%8F%E8%AE%AE.md">274.定义联动协议</a>
311+
- <a href="./可视化搭建/275.%E7%BB%84%E4%BB%B6%E5%80%BC%E6%A0%A1%E9%AA%8C.md">275.组件值校验</a>
311312

312313
### SQL
313314

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
组件值校验,即在组件值变化时判断是否满足校验逻辑,若不满足校验逻辑,可以拿到校验错误信息进行错误提示或其他逻辑处理。
2+
3+
声明 `valueValidator` 可开启值校验:
4+
5+
```js
6+
import { ComponentMeta } from "designer";
7+
8+
const input: ComponentMeta = {
9+
componentName: "input",
10+
element: Input,
11+
valueValidator: () => ({
12+
required: true,
13+
maximum: 10,
14+
}),
15+
};
16+
```
17+
18+
如上面的例子,相当于对组件值做了 “不能为 `undefined` 且最大值为 10” 的限制。
19+
20+
- 可以内置 [JSONSchema validate](https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6) 的全部校验规则作为内置规则。
21+
- 支持拓展自定义校验规则。
22+
- 支持异步校验。
23+
- 可以用 selector 绑定任意变量(如全局状态 `state` 或者当前组件实例的 `props` 来灵活定义组件值校验规则)。
24+
25+
当校验出错时,框架也不会做任何处理,而是将错误抛给业务,由业务来判断如何处理错误。
26+
27+
接下来我们来详细说说每一项特征。
28+
29+
## 错误处理
30+
31+
定义了组件值校验后,当校验错误出现时,可以通过 `selector``validateError` 拿到错误信息:
32+
33+
```js
34+
const input: ComponentMeta = {
35+
componentName: "input",
36+
element: Input,
37+
valueValidator: () => ({
38+
required: true,
39+
maximum: 10,
40+
}),
41+
runtimeProps: ({ selector }) => ({
42+
errorName: selector(({ validateError }) => validateError.ruleName),
43+
errorMessage: selector(({ validateError }) => validateError.payload),
44+
}),
45+
};
46+
```
47+
48+
- `ruleName`: 校验规则名称。
49+
- `payload`: 该规则未命中时的返回值,校验函数返回什么,这里拿到的就是什么。内置的校验函数返回的是错误信息文案。
50+
51+
拿到校验错误后,通过 `runtimeProps` 传给组件,我们可通过组件自身或 `element` 增加统一的组件 React 容器层处理并展示这些错误信息。
52+
53+
也可以使用 `fetcher` 接收这个错误,并调整取数参数。总之支持 `selector` 的地方都可以响应校验错误,如何使用完全由你决定。
54+
55+
## 自定义校验规则
56+
57+
`createDesigner` 传递的中间件可以拓展自定义校验规则:
58+
59+
```js
60+
import { createMiddleware } from "designer";
61+
const myMiddleware = createMiddleware({
62+
validateRules: {
63+
// 自定义校验规则,判断是否为空字符串
64+
isEmptyString: (value, options?: { errorMessage?: string }) => {
65+
if (value === "") {
66+
return true;
67+
}
68+
return options.errorMessage;
69+
},
70+
},
71+
});
72+
```
73+
74+
通过 `validateRules` 定义自定义校验规则后,就可以在 `valueValidator` 中使用了:
75+
76+
```js
77+
const input: ComponentMeta = {
78+
componentName: "input",
79+
element: Input,
80+
valueValidator: () => ({
81+
isEmptyString: {
82+
errorMessage: "字符串必须为空",
83+
},
84+
}),
85+
};
86+
```
87+
88+
## 用 selector 绑定校验规则
89+
90+
利用 `selector` 将校验规则绑定到任意状态,比如:
91+
92+
```js
93+
const input: ComponentMeta = {
94+
componentName: "input",
95+
element: Input,
96+
valueValidator: ({ selector }) => selector(({ props }) => props.validator),
97+
};
98+
```
99+
100+
上面的例子,将所有组件名为 `input` 组件的校验规则绑定到当前组件实例的 `props.validator` 上。
101+
102+
```js
103+
const input: ComponentMeta = {
104+
componentName: "input",
105+
element: Input,
106+
valueValidator: ({ selector }) =>
107+
selector(({ state }) => state.validatorInfo),
108+
};
109+
```
110+
111+
上面的例子,将所有组件名为 `input` 组件的校验规则绑定绑定到全局状态 `state.validatorInfo` 上。
112+
113+
## 异步校验
114+
115+
将自定义校验函数定义为异步函数,就可以定义异步校验。
116+
117+
```js
118+
const myMiddleware = createMiddleware({
119+
validateRules: {
120+
isEmptyString: async (value, options?: { errorMessage?: string }) => {
121+
await wait(1000);
122+
if (value === "") {
123+
return true;
124+
}
125+
return options.errorMessage;
126+
},
127+
},
128+
});
129+
```
130+
131+
如上所示,定义了 `isEmptyString` 的错误校验规则,那么当校验函数执行完后,在 1s 后将会出现校验信息。
132+
133+
## 总结
134+
135+
组件值校验依然提供了强大的灵活拓展性,以下几种定制能力相互正交,将灵活性成倍放大:
136+
137+
1. `valueValidator` 利用 `selector` 绑定任意值,这样既可以定义固定的校验规则,也可以定义跟随全局状态变化的校验规则,也可定义跟随当前组件实例 props 变化的校验规则。
138+
2. 在此基础上,还可以自定义校验规则,且支持异步校验。
139+
3. 更精彩的是,对值校验失败时,如何处理校验失败的表现交给了业务层。我们再次依托强大的 `selector` 设计,将校验错误传给 `selector`,就让校验错误的用法产生了无限可能。比如用在 `runtimeProps` 可以让渲染响应校验错误,用在 `fetcher` 可以让查询响应校验错误。
140+
141+
> 讨论地址是:[精读《组件值校验》· Issue #473 · dt-fe/weekly](https://github.com/dt-fe/weekly/issues/473)
142+
143+
**如果你想参与讨论,请 [点击这里](https://github.com/dt-fe/weekly),每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。**
144+
145+
> 关注 **前端精读微信公众号**
146+
147+
<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg">
148+
149+
> 版权声明:自由转载-非商用-非衍生-保持署名([创意共享 3.0 许可证](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)

0 commit comments

Comments
 (0)