2019-12-17 22:25:28 +08:00
|
|
|
|
---
|
2020-01-02 16:05:59 +08:00
|
|
|
|
order: 8
|
2019-12-17 22:25:28 +08:00
|
|
|
|
title: 从 v3 到 v4
|
|
|
|
|
---
|
|
|
|
|
|
2020-01-04 07:06:13 +08:00
|
|
|
|
本文档将帮助你从 antd `3.x` 版本升级到 antd `4.x` 版本,如果你是 `2.x` 或者更老的版本,请先参考之前的[升级文档](https://github.com/ant-design/ant-design/blob/2adf8ced24da7b3cb46a3475854a83d76a98c536/CHANGELOG.zh-CN.md#300)升级到 3.x。
|
2019-12-17 22:25:28 +08:00
|
|
|
|
|
2020-01-04 07:06:13 +08:00
|
|
|
|
## 升级准备
|
|
|
|
|
|
|
|
|
|
1. 请先升级到 3.x 的最新版本,按照控制台 warning 信息移除/修改相关的 API。
|
|
|
|
|
2. 升级项目 React 16.12.0 以上。
|
2020-04-07 12:14:06 +08:00
|
|
|
|
- 如果你仍在使用 React 15,请参考 [React 16 升级文档](https://reactjs.org/blog/2017/09/26/react-v16.0.html#breaking-changes)。
|
|
|
|
|
- 其余 React 16 废弃生命周期 API 请参考 [迁移导引](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path)。
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
## 4.0 有哪些不兼容的变化
|
|
|
|
|
|
|
|
|
|
### 设计规范调整
|
|
|
|
|
|
|
|
|
|
- 行高从 `1.5`(`21px`) 调整为 `1.5715`(`22px`)。
|
2020-11-08 15:04:02 +08:00
|
|
|
|
- 基础圆角调整,由 `4px` 改为 `2px`。
|
2020-01-06 10:58:56 +08:00
|
|
|
|
- Selected 颜色和 Hovered 颜色进行了交换。
|
2020-01-04 07:06:13 +08:00
|
|
|
|
- 全局阴影优化,调整为三层阴影区分控件层次关系。
|
|
|
|
|
- 气泡确认框中图标的使用改变,由问号改为感叹号。
|
|
|
|
|
- 部分组件选中颜色统一改为 `@blue-1: #E6F7FF`,对应 `hover` 颜色改为 `@gray-2: #FAFAFA`。
|
|
|
|
|
- 报错色色值调整,由 `@red-5: #F5222D` 改为 `@red-5: #FF4D4F`。
|
|
|
|
|
- 分割线颜色明度降低,由 `#E8E8E8` 改为 `#F0F0F0`。
|
|
|
|
|
- DatePicker 交互重做,面板和输入框分离,范围选择现可单独选择开始和结束时间。
|
|
|
|
|
- Table 默认背景颜色从透明修改为白色。
|
2020-02-07 11:08:16 +08:00
|
|
|
|
- Tabs 火柴棍样式缩短为和文字等长。
|
2020-07-15 12:28:39 +08:00
|
|
|
|
- Tabs 交互重做,DOM 结构改变。`4.3.0`
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
### 兼容性调整
|
|
|
|
|
|
|
|
|
|
- IE 最低支持版本为 IE 11。
|
|
|
|
|
- React 最低支持版本为 React 16.9,部分组件开始使用 hooks 进行重构。
|
2020-04-28 12:19:15 +08:00
|
|
|
|
- 重构通过 `useMemo` 进行性能优化,请勿使用 mutable data 作为参数。
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
#### 移除废弃的 API
|
|
|
|
|
|
|
|
|
|
- 移除了 LocaleProvider,请使用 `ConfigProvider` 替代。
|
|
|
|
|
- 移除了 Mention,请使用 `Mentions` 替代。
|
|
|
|
|
- 移除了 Alert 的 `iconType` 属性,请使用 `icon` 替代。
|
|
|
|
|
- 移除了 Modal.xxx 的 `iconType` 属性,请使用 `icon` 替代。
|
|
|
|
|
- 移除了 Form.create 方法,`form` 现可由 `Form.useForm` 获取。
|
|
|
|
|
- 移除了 Form.Item 的 `id` 属性,请使用 `htmlFor` 替代。
|
|
|
|
|
- 移除了 Typography 的 `setContentRef` 属性,请使用 `ref` 替代。
|
|
|
|
|
- 移除了 TimePicker 的 `allowEmpty` 属性,请使用 `allowClear` 替代。
|
|
|
|
|
- 移除了 Tag 的 `afterClose` 属性,请使用 `onClose` 替代。
|
|
|
|
|
- 移除了 Card 的 `noHovering` 属性,请使用 `hoverable` 替代。
|
|
|
|
|
- 移除了 Carousel 的 `vertical` 属性,请使用 `dotPosition` 替代。
|
|
|
|
|
- 移除了 Drawer 的 `wrapClassName` 属性,请使用 `className` 替代。
|
|
|
|
|
- 移除了 TextArea 的 `autosize` 属性,请使用 `autoSize` 替代。
|
|
|
|
|
- 移除了 Affix 的 `offset` 属性,请使用 `offsetTop` 替代。
|
|
|
|
|
- 移除了 Transfer 的 `onSearchChange` 属性,请使用 `onSearch` 替代。
|
|
|
|
|
- 移除了 Transfer 的 `body` 属性,请使用 `children` 替代。
|
|
|
|
|
- 移除了 Transfer 的 `lazy` 属性,它并没有起到真正的优化效果。
|
|
|
|
|
- 移除了 Select 的 `combobox` 模式,请使用 `AutoComplete` 替代。
|
2020-05-29 23:50:56 +08:00
|
|
|
|
- 移除了 Table 的 `rowSelection.hideDefaultSelections` 属性,请在 `rowSelection.selections` 中使用 `SELECTION_ALL` 和 `SELECTION_INVERT` 替代,[自定义选择项](/components/table/#components-table-demo-row-selection-custom)。
|
2020-08-19 09:48:51 +08:00
|
|
|
|
- 废弃 Button.Group,请使用 `Space` 代替。
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
#### 图标升级
|
|
|
|
|
|
|
|
|
|
在 `antd@3.9.0` 中,我们引入了 svg 图标([为何使用 svg 图标?](https://github.com/ant-design/ant-design/issues/10353))。使用了字符串命名的图标 API 无法做到按需加载,因而全量引入了 svg 图标文件,这大大增加了打包产物的尺寸。在 4.0 中,我们调整了图标的使用 API 从而支持 tree shaking,减少 antd 默认包体积约 150 KB(Gzipped)。
|
|
|
|
|
|
|
|
|
|
旧版 Icon 使用方式将被废弃:
|
|
|
|
|
|
|
|
|
|
```jsx
|
|
|
|
|
import { Icon, Button } from 'antd';
|
|
|
|
|
|
|
|
|
|
const Demo = () => (
|
|
|
|
|
<div>
|
|
|
|
|
<Icon type="smile" />
|
|
|
|
|
<Button icon="smile" />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
4.0 中会采用按需引入的方式:
|
|
|
|
|
|
|
|
|
|
```diff
|
2020-02-18 17:27:13 +08:00
|
|
|
|
import { Button } from 'antd';
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
2020-02-18 17:27:13 +08:00
|
|
|
|
// tree-shaking supported
|
2020-01-04 07:06:13 +08:00
|
|
|
|
- import { Icon } from 'antd';
|
|
|
|
|
+ import { SmileOutlined } from '@ant-design/icons';
|
|
|
|
|
|
2020-02-18 17:27:13 +08:00
|
|
|
|
const Demo = () => (
|
|
|
|
|
<div>
|
|
|
|
|
- <Icon type="smile" />
|
|
|
|
|
+ <SmileOutlined />
|
|
|
|
|
<Button icon={<SmileOutlined />} />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
2020-02-18 17:27:13 +08:00
|
|
|
|
// or directly import
|
|
|
|
|
import SmileOutlined from '@ant-design/icons/SmileOutlined';
|
2020-01-04 07:06:13 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
你将仍然可以通过兼容包继续使用:
|
|
|
|
|
|
|
|
|
|
```jsx
|
|
|
|
|
import { Button } from 'antd';
|
|
|
|
|
import { Icon } from '@ant-design/compatible';
|
|
|
|
|
|
|
|
|
|
const Demo = () => (
|
|
|
|
|
<div>
|
|
|
|
|
<Icon type="smile" />
|
|
|
|
|
<Button icon="smile" />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 组件重构
|
|
|
|
|
|
2020-02-18 17:27:13 +08:00
|
|
|
|
- Form 重写
|
|
|
|
|
- 不再需要 `Form.create`。
|
|
|
|
|
- 嵌套字段支持从 `'xxx.yyy'` 改成 `['xxx', 'yyy']`。
|
|
|
|
|
- 迁移文档请查看[此处](/components/form/v3)。
|
2020-01-04 07:06:13 +08:00
|
|
|
|
- DatePicker 重写
|
|
|
|
|
- 提供 `picker` 属性用于选择器切换。
|
|
|
|
|
- 范围选择现在可以单独选择开始和结束时间。
|
2020-02-19 13:51:45 +08:00
|
|
|
|
- `onPanelChange` 在面板值变化时也会触发。
|
2020-02-25 19:41:43 +08:00
|
|
|
|
- [自定义单元格样式](/components/date-picker-cn/#components-date-picker-demo-date-render)的类名从 `ant-calendar-date` 改为 `ant-picker-cell-inner`。
|
2020-02-19 10:02:12 +08:00
|
|
|
|
- Tree、Select、TreeSelect、AutoComplete 重新写
|
|
|
|
|
- 使用虚拟滚动。
|
2020-04-18 21:10:01 +08:00
|
|
|
|
- `onBlur` 时不再修改选中值,且返回 React 原生的 `event` 对象。
|
2020-02-19 17:58:52 +08:00
|
|
|
|
- AutoComplete 不再支持 `optionLabelProp`,请直接设置 Option `value` 属性。
|
2020-09-21 16:24:48 +08:00
|
|
|
|
- AutoComplete 选项与 Select 对齐,请使用 `options` 代替 `dataSource`。
|
2020-03-25 12:57:57 +08:00
|
|
|
|
- Select 移除 `dropdownMenuStyle` 属性。
|
2020-04-15 10:04:01 +08:00
|
|
|
|
- 如果你需要设置弹窗高度请使用 `listHeight` 来代替 `dropdownStyle` 的高度样式。
|
2020-04-22 21:24:36 +08:00
|
|
|
|
- `filterOption` 第二个参数直接返回原数据,不在需要通过 `option.props.children` 来进行匹配。
|
2020-08-15 16:28:58 +08:00
|
|
|
|
- Tree、TreeSelect 同时指定 `title` 和 `label` 的时候,会选择显示 `label`。为了 `labelInValue` 行为一致进行了该调整。[新行为](https://codesandbox.io/s/keen-curran-d3qnp)(在第一个节点展示 'label'),[旧行为](https://codesandbox.io/s/muddy-darkness-57lb3)(在第一个节点展示 'title')。
|
2020-10-22 22:57:20 +08:00
|
|
|
|
- Tree 传入内容采用 `treeData` 属性,来代替 `TreeNode` 方式,TreeNode 依然可用,但是会在控制台抛出警告。
|
2020-01-04 07:06:13 +08:00
|
|
|
|
- Grid 组件使用 flex 布局。
|
|
|
|
|
- Button 的 `danger` 现在作为一个属性而不是按钮类型。
|
2020-01-09 11:13:07 +08:00
|
|
|
|
- Input、Select 的 `value` 为 `undefined` 时改为非受控状态。
|
2020-02-18 17:27:13 +08:00
|
|
|
|
- Table 重写
|
|
|
|
|
- 在没有 `columns` 时仍然会保留一列。
|
|
|
|
|
- 嵌套 `dataIndex` 支持从 `'xxx.yyy'` 改成 `['xxx', 'yyy']`。
|
2020-04-09 10:52:02 +08:00
|
|
|
|
- Pagination 自 `4.1.0` 起大于 50 条数据默认会展示 `pageSize` 切换器,这条规则同样会运用于 Table 上。
|
2020-06-15 12:27:17 +08:00
|
|
|
|
- Tabs 重写([4.3.0](https://github.com/ant-design/ant-design/pull/24552))
|
|
|
|
|
- Dom 结构变化,如有覆盖样式需要仔细检查。
|
|
|
|
|
- 横向滚动交互变化,`onPrevClick` 和 `onNextClick` 不再工作。
|
2020-02-18 17:27:13 +08:00
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
<Table
|
|
|
|
|
columns={[
|
|
|
|
|
{
|
|
|
|
|
title: 'Age',
|
|
|
|
|
- dataIndex: 'user.age',
|
|
|
|
|
+ dataIndex: ['user', 'age'],
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
```
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
## 开始升级
|
|
|
|
|
|
|
|
|
|
你可以手动对照上面的列表逐条检查代码进行修改,另外,我们也提供了一个 codemod cli 工具 [@ant-design/codemod-v4](https://github.com/ant-design/codemod-v4) 以帮助你快速升级到 v4 版本。
|
2019-12-17 22:25:28 +08:00
|
|
|
|
|
|
|
|
|
在运行 codemod cli 前,请先提交你的本地代码修改。
|
|
|
|
|
|
|
|
|
|
```shell
|
|
|
|
|
# 通过 npx 直接运行
|
|
|
|
|
npx -p @ant-design/codemod-v4 antd4-codemod src
|
|
|
|
|
|
|
|
|
|
# 或者全局安装
|
|
|
|
|
# 使用 npm
|
|
|
|
|
npm i -g @ant-design/codemod-v4
|
|
|
|
|
# 或者使用 yarn
|
2020-01-06 15:25:07 +08:00
|
|
|
|
yarn global add @ant-design/codemod-v4
|
2019-12-17 22:25:28 +08:00
|
|
|
|
|
|
|
|
|
# 运行
|
|
|
|
|
antd4-codemod src
|
|
|
|
|
```
|
|
|
|
|
|
2020-02-18 17:27:13 +08:00
|
|
|
|
<img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*QdcbQoLC-cQAAAAAAAAAAABkARQnAQ" alt="codemod running" width="720" />
|
2020-01-05 21:10:07 +08:00
|
|
|
|
|
2020-01-04 07:06:13 +08:00
|
|
|
|
对于无法自动修改的部分,codemod 会在命令行进行提示,建议按提示手动修改。修改后可以反复运行上述命令进行检查。
|
|
|
|
|
|
2020-02-18 17:27:13 +08:00
|
|
|
|
<img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*KQwWSrPirlUAAAAAAAAAAABkARQnAQ" alt="contains an invalid icon" width="720" />
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
> 注意 codemod 不能涵盖所有场景,建议还是要按不兼容的变化逐条排查。
|
2019-12-17 22:25:28 +08:00
|
|
|
|
|
2020-01-04 07:06:13 +08:00
|
|
|
|
### 迁移工具修改详情
|
|
|
|
|
|
|
|
|
|
`@ant-design/codemod-v4` 会帮你迁移到 antd v4, 废弃的组件则通过 `@ant-design/compatible` 保持运行, 一般来说你无需手动迁移。下方内容详细介绍了整体的迁移和变化,你也可以参照变动手动修改。
|
2019-12-17 22:25:28 +08:00
|
|
|
|
|
|
|
|
|
#### 将已废弃的 `Form` 和 `Mention` 组件通过 `@ant-design/compatible` 包引入
|
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
- import { Form, Input, Button, Mention } from 'antd';
|
|
|
|
|
+ import { Form, Mention } from '@ant-design/compatible';
|
|
|
|
|
+ import '@ant-design/compatible/assets/index.css';
|
|
|
|
|
+ import { Input, Button } from 'antd';
|
|
|
|
|
|
|
|
|
|
ReactDOM.render( (
|
|
|
|
|
<div>
|
|
|
|
|
<Form>
|
|
|
|
|
{getFieldDecorator('username')(<Input />)}
|
|
|
|
|
<Button>Submit</Button>
|
|
|
|
|
</Form>
|
|
|
|
|
<Mention
|
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
defaultValue={toContentState('@afc163')}
|
|
|
|
|
defaultSuggestions={['afc163', 'benjycui']}
|
|
|
|
|
onSelect={onSelect}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
```
|
|
|
|
|
|
2020-01-04 07:06:13 +08:00
|
|
|
|
> **注意:**从 `@ant-design/compatible` 引入的老版本 Form 组件,样式类名会从 `.ant-form` 变成 `.ant-legacy-form`,如果你对其进行了样式覆盖,也需要相应修改。
|
|
|
|
|
|
|
|
|
|
#### 用新的 `@ant-design/icons` 替换字符串类型的 `icon` 属性值
|
2019-12-17 22:25:28 +08:00
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
import { Avatar, Button, Result } from 'antd';
|
|
|
|
|
+ import { QuestionOutlined, UserOutlined } from '@ant-design/icons';
|
|
|
|
|
|
|
|
|
|
ReactDOM.render(
|
|
|
|
|
<div>
|
|
|
|
|
- <Button type="primary" shape="circle" icon="search" />
|
|
|
|
|
+ <Button type="primary" shape="circle" icon={SearchOutlined} />
|
|
|
|
|
- <Avatar shape="square" icon="user" />
|
|
|
|
|
+ <Avatar shape="square" icon={UserOutlined} />
|
|
|
|
|
<Result
|
|
|
|
|
- icon="question"
|
|
|
|
|
+ icon={<QuestionOutlined />}
|
|
|
|
|
title="Great, we have done all the operations!"
|
|
|
|
|
extra={<Button type="primary">Next</Button>}
|
|
|
|
|
/>
|
|
|
|
|
</div>,
|
|
|
|
|
mountNode,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 将 v3 Icon 组件转换成 `@ant-design/icons` 中引入
|
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
- import { Icon, Input } from 'antd';
|
|
|
|
|
+ import { Input } from 'antd';
|
|
|
|
|
+ import Icon, { CodeFilled, SmileOutlined, SmileTwoTone } from '@ant-design/icons';
|
|
|
|
|
|
|
|
|
|
const HeartSvg = () => (
|
|
|
|
|
<svg width="1em" height="1em" fill="currentColor" viewBox="0 0 1024 1024">
|
|
|
|
|
<path d="M923 plapla..." />
|
|
|
|
|
</svg>
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const HeartIcon = props => <Icon component={HeartSvg} {...props} />;
|
|
|
|
|
|
|
|
|
|
ReactDOM.render(
|
|
|
|
|
<div>
|
|
|
|
|
- <Icon type="code" theme="filled" />
|
|
|
|
|
+ <CodeFilled />
|
|
|
|
|
- <Icon type="smile" theme="twoTone" twoToneColor="#eb2f96" />
|
|
|
|
|
+ <SmileTwoTone twoToneColor="#eb2f96" />
|
|
|
|
|
- <Icon type="code" theme={props.fill ? 'filled' : 'outlined'} />
|
|
|
|
|
+ <LegacyIcon type="code" theme={props.fill ? 'filled' : 'outlined'} />
|
|
|
|
|
<HeartIcon />
|
|
|
|
|
<Icon viewBox="0 0 24 24">
|
|
|
|
|
<title>Cool Home</title>
|
|
|
|
|
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
|
|
|
|
|
</Icon>
|
|
|
|
|
<Input suffix={<SmileOutlined />} />
|
|
|
|
|
</div>,
|
|
|
|
|
mountNode,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 将 v3 LocaleProvider 组件转换成 v4 ConfigProvider 组件
|
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
- import { LocaleProvider } from 'antd';
|
|
|
|
|
+ import { ConfigProvider } from 'antd';
|
|
|
|
|
|
|
|
|
|
ReactDOM.render(
|
|
|
|
|
- <LocaleProvider {...yourConfig}>
|
|
|
|
|
+ <ConfigProvider {...yourConfig}>
|
|
|
|
|
<Main />
|
|
|
|
|
- </LocaleProvider>
|
|
|
|
|
+ </ConfigProvider>
|
|
|
|
|
mountNode,
|
|
|
|
|
);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 将 `Modal.method()` 中字符串 icon 属性的调用转换成从 `@ant-design/icons` 中引入
|
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
import { Modal } from 'antd';
|
|
|
|
|
+ import { AntDesignOutlined } from '@ant-design/icons';
|
|
|
|
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
- icon: 'ant-design',
|
|
|
|
|
+ icon: <AntDesignOutlined />,
|
|
|
|
|
title: 'Do you Want to delete these items?',
|
|
|
|
|
content: 'Some descriptions',
|
|
|
|
|
onOk() {
|
|
|
|
|
console.log('OK');
|
|
|
|
|
},
|
|
|
|
|
onCancel() {
|
|
|
|
|
console.log('Cancel');
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
```
|
2020-01-04 07:06:13 +08:00
|
|
|
|
|
|
|
|
|
## 遇到问题
|
|
|
|
|
|
|
|
|
|
v4 做了非常多的细节改进和重构,我们尽可能收集了已知的所有不兼容变化和相关影响,但是有可能还是有一些场景我们没有考虑到。如果你在升级过程中遇到了问题,请到 [GitHub issues](http://new-issue.ant.design/) 和 [codemod Issues](https://github.com/ant-design/codemod-v4/issues) 进行反馈。我们会尽快响应和相应改进这篇文档。
|