mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-25 16:58:00 +08:00
111 lines
4.3 KiB
Markdown
111 lines
4.3 KiB
Markdown
---
|
||
title: 所见即所得
|
||
date: 2023-05-10
|
||
author: zombieJ
|
||
zhihu_url: https://zhuanlan.zhihu.com/p/639266810
|
||
yuque_url: https://www.yuque.com/ant-design/ant-design/vhife82m442inpws
|
||
juejin_url: https://juejin.cn/post/7322296529783078949
|
||
---
|
||
|
||
在日常开发过程中,你是否思考过一个问题。那就是范围限定和实际值不同的时候,应该如何去处理?假设我们有一个展示组件,它很简单的将你的值进行展示:
|
||
|
||
```tsx
|
||
interface StrProps {
|
||
value: string;
|
||
}
|
||
|
||
function MyStr({ value }: StrProps) {
|
||
return <div>{value}</div>;
|
||
}
|
||
<MyStr value="Hello World" />;
|
||
```
|
||
|
||
毫无疑问,页面上就该展示 `Hello World`。接着,我们加个范围限定:
|
||
|
||
```tsx
|
||
interface StrProps {
|
||
value: string;
|
||
maxLen?: number;
|
||
}
|
||
```
|
||
|
||
这个时候如果我们使用了超出范围的值应该显示什么?
|
||
|
||
```tsx
|
||
<MyStr value="Hello World" maxLen={5}>
|
||
```
|
||
|
||
“显而易见”,既然有了 `maxLen`,那么就应该显示 `Hello` 而非 `Hello World`。
|
||
|
||
但是这种直觉的处理方式,却并不是所有情况下都是正确的。如果你使用原生的 input,你就发现表现并不是这样的:
|
||
|
||
```tsx
|
||
<input value="Hello World" maxLength={5} />
|
||
```
|
||
|
||
<img height="50" alt="input limit" src="https://github.com/ant-design/ant-design/assets/5378891/31352b9b-6d68-4a42-832d-5a639fed80cc">
|
||
|
||
按照标准描述,`maxLength` 只限制用户输入。这是标准错了吗?
|
||
|
||
> A form control maxlength attribute, controlled by the dirty value flag, declares a limit on the number of characters a user can input.
|
||
|
||
### “多此一举”
|
||
|
||
带着上面的疑问,我们想象一个输入场景。现在你有一个电商系统,给商品设定价格:
|
||
|
||
```tsx
|
||
<Form>
|
||
<Form.Item label="Name" name="name">
|
||
<Input />
|
||
</Form.Item>
|
||
|
||
<Form.Item label="Price" name="price">
|
||
<InputNumber />
|
||
</Form.Item>
|
||
</Form>
|
||
```
|
||
|
||
<img height="160" alt="Form" src="https://github.com/ant-design/ant-design/assets/5378891/f9ad7f13-d2bf-4537-9265-48789e2c4d0e">
|
||
|
||
某天你的经理说,我们的商品价格按规定不能超过 99 元,你要直接在表单上做限制。这个改动并不难:
|
||
|
||
```diff
|
||
-- <InputNumber />
|
||
++ <InputNumber max={99} />
|
||
```
|
||
|
||
但是对于现有的商品,我们显然不能直接在表单上做限制。否则,用户在编辑商品的时候,就会发现自己的商品价格被改了。这显然是不合理的。
|
||
|
||
<img height="162" alt="Form modify" src="https://github.com/ant-design/ant-design/assets/5378891/08d07ec2-7be8-45fa-b30b-51395252bcd0">
|
||
|
||
(用户永远无法明白为什么后台的数据和看到的对不上了)
|
||
|
||
实际上在很多场景下,组件都不应该直接修改实际值。尤其是输入型组件,擅自更改展示值会出现非常严重的后果。
|
||
|
||
### 所见即所得
|
||
|
||
在组件库层面,我们不能“推测”用户的使用场景,因而需要以最保守的方式实现边界场景的处理。但是同时我们其实可以做一些优化手段。比如说将限制设置到 Form.Item 的 `rules` 上,利用表单校验能力来做限制:
|
||
|
||
<img height="160" alt="Form rules" src="https://github.com/ant-design/ant-design/assets/5378891/52b35fb3-a800-447f-85b3-684d9a65c8d1">
|
||
|
||
对于一些组件本身,也可以添加显式的样式提醒:
|
||
|
||
<img height="40" alt="InputNumber" src="https://github.com/ant-design/ant-design/assets/5378891/e14ab877-4778-49c7-af75-91e36e60ce0f">
|
||
|
||
对于非输入型自定义组件,也可以考虑通过设计来提醒用户。比如说我们可以在展示组件上添加一个 Tooltip:
|
||
|
||
```tsx
|
||
// Same demo we've seen before
|
||
<MyStr value="Hello World" maxLen={5}>
|
||
```
|
||
|
||
<img height="90" alt="Customize" src="https://github.com/ant-design/ant-design/assets/5378891/18b095c4-eee9-45df-aa05-b4f5c20c81f8">
|
||
|
||
或者使用一些其他的展示方式:
|
||
|
||
<img height="40" alt="Ellipsis" src="https://github.com/ant-design/ant-design/assets/5378891/24162b19-985c-4fc4-908a-cdddfc507fc9">
|
||
|
||
### 总结
|
||
|
||
在进行组件研发时,需要慎重处理边界场景。在大型项目中,上游使用者可能并不知道你的内部逻辑是如何处理的。因而随着复杂度以及使用场景的增加,我们更加推荐对于默认行为总是选择保守的处理方式。而对于不满足需求的情况,可以通过 HOC 的形式或者是一些额外的 Props 配置来实现,以防止开发者在使用时有过多的约定而不知。
|