Skip to content

Commit 7acd0e9

Browse files
committed
chore: update
0 parents  commit 7acd0e9

File tree

389 files changed

+21509
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

389 files changed

+21509
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
```css
2+
.ant-menu {
3+
// 一级菜单
4+
> .ant-menu-item {
5+
// 一级菜单hover样式
6+
&-active {
7+
}
8+
// 一级菜单selected样式
9+
&.ant-menu-item-selected {
10+
}
11+
}
12+
// 子菜单
13+
.ant-menu-submenu {
14+
// 子菜单标题
15+
&-title {
16+
}
17+
&-active {
18+
// 子菜单标题hover样式
19+
.ant-menu-submenu-title {
20+
}
21+
}
22+
.ant-menu-sub {
23+
// 二级菜单
24+
> .ant-menu-item {
25+
// 二级菜单hover样式
26+
&-active {
27+
}
28+
// 二级菜单selected样式
29+
&.ant-menu-item-selected {
30+
}
31+
}
32+
}
33+
}
34+
}
35+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Modal在弹出后,如果其内容需要滚动,会与文档的滚动发生冲突,也称为滚动穿透问题。所以在Modal弹出后,需要将文档顶层的scroll隐藏,Modal关闭时恢复。即:
2+
3+
```js
4+
// 隐藏顶层scroll
5+
document.documentElement.style.overflow = 'hidden'
6+
// 恢复顶层scroll
7+
document.documentElement.style.overflow = 'auto'
8+
```
9+
> 或者body.style.overflow = 'hidden'
10+
11+
Antd Modal默认会做以上事情。

Ant-Design组件/TableTransfer.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
```tsx
2+
import { Table, Transfer, TransferProps } from 'antd';
3+
import { ColumnsType } from 'antd/lib/table';
4+
import { TableRowSelection, TablePaginationConfig } from 'antd/lib/table/interface';
5+
import difference from 'lodash/difference';
6+
import React from 'react';
7+
8+
interface TableTransferProps<T> extends TransferProps<T> {
9+
leftColumns: ColumnsType<T>;
10+
leftPagination?: TablePaginationConfig;
11+
12+
rightColumns: ColumnsType<T>;
13+
rightPagination?: TablePaginationConfig;
14+
}
15+
16+
export function TableTransfer<T>({
17+
leftColumns,
18+
rightColumns,
19+
leftPagination,
20+
rightPagination,
21+
...restProps
22+
}: TableTransferProps<T>) {
23+
return (
24+
<Transfer {...restProps}>
25+
{({
26+
direction,
27+
filteredItems,
28+
onItemSelectAll,
29+
onItemSelect,
30+
selectedKeys: listSelectedKeys,
31+
disabled: listDisabled,
32+
}) => {
33+
const columns = direction === 'left' ? leftColumns : rightColumns;
34+
const pagination = direction === 'left' ? leftPagination : rightPagination;
35+
36+
const rowSelection: TableRowSelection<any> = {
37+
getCheckboxProps: (item) => ({ disabled: listDisabled || item.disabled }),
38+
onSelectAll(selected, selectedRows) {
39+
const treeSelectedKeys = selectedRows
40+
.filter((item) => !item.disabled)
41+
.map(({ key }) => key);
42+
const diffKeys = selected
43+
? difference(treeSelectedKeys, listSelectedKeys)
44+
: difference(listSelectedKeys, treeSelectedKeys);
45+
onItemSelectAll(diffKeys, selected);
46+
},
47+
onSelect({ key }, selected) {
48+
onItemSelect(key, selected);
49+
},
50+
selectedRowKeys: listSelectedKeys,
51+
};
52+
53+
return (
54+
<Table
55+
rowSelection={rowSelection}
56+
columns={columns}
57+
dataSource={filteredItems}
58+
pagination={pagination}
59+
size="small"
60+
style={{ pointerEvents: listDisabled ? 'none' : null }}
61+
onRow={({ key, disabled: itemDisabled }) => ({
62+
onClick: () => {
63+
if (itemDisabled || listDisabled) return;
64+
onItemSelect(key, !listSelectedKeys.includes(key));
65+
},
66+
})}
67+
/>
68+
);
69+
}}
70+
</Transfer>
71+
);
72+
}
73+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
1. DatePicker 有两个属性控制其“外貌”,一个是 picker,一个是 mode。如果想动态改变 DatePicker 类型需要同时改变 picker 和 mode。
2+
3+
2. Popover、Select、AutoComplete 等有弹出层的组件,弹出层 Portal 默认是挂到 body 下的,所以写 css 嵌套的时候匹配不到,而且在上层 Layout 容器为 fixed 定位时,滚动时弹出层会脱离弹出时的锚点。为了解决这些问题,它们都有一个 getPopupContainer 方法用来指定挂到那个 dom 节点下(配合 useRef)。一般都会用到的。
4+
5+
3. Table 组件的 dataSource 是需要 key 的,但不需要手动遍历一遍添加 key 属性,使用 rowKey 即可。
6+
7+
4. Modal 组件 visible 为 false 时默认是不销毁子元素的(可以理解为默认是 keep-alive 的),如果 Model 内组件中用了定时器(比如 react-use 的 useInterval),你会发现当 Model 消失时,定时器还在跑,useEffect 没有执行 clean subscription。Modal 提供了一个属性用来控制隐藏时是否销毁组件(建议设置为 true):destroyOnClose,默认 false。
8+
9+
5. antd 中想要拿到非受控的 Input 组件的 value 只有一个办法,就是使用 Form Field,在外面包一层 Form>Form.Item 组件,然后使用 form.getFieldValue 获取相应字段的值。Input 组件没有 forwardRef。
10+
11+
6. Table 组件的 columns 最后一项的 width 最好不要指定,所有的 column.width 加起来不要正好等于容器宽度,否则在某些浏览器上会出现谜之抖动。
12+
13+
7. Menu 中使用 SubMenu,SubMenu 的 Item 默认有一个内联的 padding-left: 48px;,这个是根据 level 和 inlineIndent 计算而来的,inlineIndent 默认为 24px,SubMenu 下的 Item 的 level(层级)为 2,所以 24\*2=48。这两个属性只有设置在 Menu 组件上才生效!SubMenu 和 Menu.Item 上设置是不起作用的!
14+
15+
8. 如果你的项目大量的去覆盖 antd 的默认样式,一定会遇到严重的 CSS Layout Shift 问题!很大一部分原因是因为 antd 组件有些样式本应该通过 props 设置,而你非要使用 css 去设置,写了很复杂的选择器甚至 important 去提高权重,加上 antd 组件几乎都自带 transition,css 文件请求与 dom 渲染之间存在时差,导致页面渲染过程惨不忍睹!所以能通过 props 去设置的样式一定不要去覆盖 css,如果需要可以将 antd 组件自带的 transition 设为 none!特别是你需要自定义其大小、样式、位置时!
16+
17+
9. 覆盖 antd 样式会导致 cls 问题,如果需要定制 antd 风格样式时,建议使用 less modifyVars,在预处理阶段就设置好样式,相关变量参考:
18+
19+
[github.com/ant-design](https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less)
20+
21+
10. Form.Item 下的默认值(defaultValue)是无法通过 setState 改变的!可以用 useEffect 来检测依赖变化同时 form.resetFields。如果是在 Modal 中使用,Modal 需设置 forceRender。
22+
23+
11. Form.Item 可以包装组件,并自动提交表单值。可以被 Form.Item 包装的组件必须在 props 提供 value 和 onChange 即使组件受控,组件 onChange 传入的值会被提交到表单。
24+
25+
12. Upload 组件提交文件上传时,建议让后端开 cors 直接发,不要自己写代理特别是 nodejs 代理,nodejs 在文件中转这里非常非常坑!!

Ant-Design组件/antd按需加载.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
按需加载适用于 ssr,因为 ssr 没有打包,是天然的代码分割。如果是 csr 那么需要 webpack 动态 import。
2+
3+
antd 官方提供了 babel-plugin-import 插件用于自动导入样式以及按需加载。
4+
5+
按需加载其实是按需导入,是 webpack 打包原理所决定的,webpack 按照 import 路径来打包,所以只要 import 的路径足够细粒度就等于实现了按需加载。
6+
7+
例如:
8+
9+
1. 如果没有使用 babel-plugin-import 插件想要实现按需加载:
10+
11+
```ts
12+
// 举例,不代表真实路径
13+
import { Button } from "antd/lib/button";
14+
import "antd/lib/button/style.less";
15+
```
16+
17+
需要把路径写得很细。
18+
19+
2. 如果使用了 babel-plugin-import 插件:
20+
21+
只需要
22+
23+
```ts
24+
import { Button } from "antd";
25+
```
26+
27+
一行即可实现自动导入对应样式和代码。
28+
29+
> 原理即是自动补全路径
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
checkbox多选组件如果需要在表单中使用,官方推荐是使用Checkbox Group。checkbox不能响应Form.Item的value和onChange,需要手动绑定:
2+
3+
```tsx
4+
const FormCheckbox = ({
5+
children,
6+
value,
7+
onChange,
8+
}: {
9+
children: ReactNode
10+
value?: boolean
11+
onChange?: (value: boolean) => void
12+
}) => {
13+
return (
14+
<Checkbox
15+
checked={value}
16+
onChange={event => onChange(event?.target?.checked)}
17+
>
18+
{children}
19+
</Checkbox>
20+
)
21+
}
22+
```

Ant-Design组件/form表单验证.md

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
示例:
2+
3+
```tsx
4+
export const UrlPrefix = /^(https|http):\/\//
5+
6+
export const UrlValidator: RuleRender = ({ getFieldValue }) => ({
7+
validator(rule, value) {
8+
if (!value || UrlPrefix.test(value)) {
9+
return Promise.resolve()
10+
}
11+
return Promise.reject('请输入正确的链接!')
12+
},
13+
})
14+
15+
const App = () => {
16+
const [form] = Form.useForm()
17+
const onFinish = ({ href }: { href: string }) => {
18+
console.log(href)
19+
}
20+
return (
21+
<Form form={form} onFinish={onFinish}>
22+
<Form.Item
23+
label="链接"
24+
name="href"
25+
initialValue={'http://saber2pr.top/'}
26+
rules={[{ required: true, message: '链接不能为空!' }, UrlValidator]}
27+
>
28+
<Input autoComplete="off" placeholder="请输入链接" />
29+
</Form.Item>
30+
</Form>
31+
)
32+
}
33+
```
34+
35+
复杂一点的,从接口获取数据校验混合正则校验:
36+
37+
组件:
38+
39+
```tsx
40+
41+
export interface InputCodeProps {
42+
value?: string;
43+
onChange?: (value: string) => void;
44+
onBlur?: VoidFunction; // 注意这里的onBlur
45+
}
46+
47+
export const InputCode: React.FC<InputCodeProps> = ({
48+
value,
49+
onChange,
50+
onBlur,
51+
}) => {
52+
return (
53+
<Space>
54+
<Input
55+
value={value}
56+
onChange={(e) => onChange(e.target.value)}
57+
onBlur={onBlur} // 注意这里的onBlur
58+
/>
59+
<span>...</span>
60+
</Space>
61+
);
62+
};
63+
```
64+
65+
form表单:
66+
67+
```tsx
68+
<Form.Item
69+
name="code"
70+
validateTrigger={['onBlur', 'onChange']} // 注意这里的onBlur
71+
rules={[
72+
{ required: true },
73+
CodeValidator, CodeDedupValidator(query?.libraryCode)
74+
]}
75+
>
76+
<InputCode/>
77+
</Form.Item>
78+
```
79+
80+
验证器:
81+
82+
```tsx
83+
export const CodeValidator: RuleRender = (form) => ({
84+
validateTrigger: 'onChange', // 这里
85+
async validator(rule, value) {
86+
if (!value) {
87+
return Promise.resolve();
88+
}
89+
if (!/[a-zA-Z0-9_]+$/.test(value)) {
90+
return Promise.reject('组件标识只能包含字母数字');
91+
}
92+
return Promise.resolve();
93+
},
94+
});
95+
96+
export const CodeDedupValidator: (libraryCode: string) => RuleRender = (libraryCode: string) => (
97+
form,
98+
) => ({
99+
validateTrigger: 'onBlur', // 注意这里onBlur
100+
async validator(rule, value) {
101+
// 请求接口
102+
const list = await queryBaseComponentList({
103+
componentCode: value,
104+
libraryCode,
105+
});
106+
107+
// 根据接口返回做校验
108+
const hasComp = getArray(list?.dataList)[0]?.code === value;
109+
if (hasComp) {
110+
return Promise.reject(`组件标识${value}已存在`);
111+
}
112+
113+
return Promise.resolve();
114+
},
115+
});
116+
117+
```

Ant-Design组件/input样式重置.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
antd 中的 Input 组件其实已经重置过样式了,但是还有一个地方需要重置一下。就是 chrome 默认会当 input 中填充值后让背景变色。
2+
3+
重置方法:
4+
5+
```css
6+
input {
7+
box-shadow: inset 0 0 0 1000px #fff !important;
8+
}
9+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
antd 中的 Table 组件自带了分页器:
2+
3+
```tsx
4+
<Table dataSource={dataSource} columns={columns} />
5+
```
6+
7+
如果表格数据太多,Table 组件 pagination 分页器会自动按 10 行/页进行自动分页。
8+
9+
但是通常情况下分页由后端实现,一次获取大量数据会给数据库带来压力。这种情况下就需要前端自定义/虚拟分页,先设置好分页总数,换页的时候调用后端接口重新装填 dataSource 并改变分页器当前页码。
10+
11+
Table 组件提供了 pagination 属性用于控制分页器,将其转换为受控组件:
12+
13+
```tsx
14+
<Table
15+
dataSource={dataSource}
16+
columns={columns}
17+
pagination={{
18+
pageSize: size,
19+
total: totalElements,
20+
current: pageIdx,
21+
onChange: changePage
22+
}}
23+
/>
24+
```
25+
26+
后端分页查询需返回当前页数据(Array)和全部页数据总数(Number)。前端使用 total/pageSize 即可进行虚拟分页数设置。

Ant-Design组件/右键菜单.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
item组件右键点击弹出菜单
2+
3+
```tsx
4+
const menu = <Menu>
5+
<Menu.Item onClick={() => onCollapseAll(node)}>
6+
{i18n.format('collapseAll')}
7+
</Menu.Item>
8+
</Menu>
9+
10+
<Dropdown trigger={['contextMenu']} overlay={menu}>
11+
<Item />
12+
</Dropdown>
13+
```

0 commit comments

Comments
 (0)