AntdV4升级到V5,时间组件momentjs替换dayjs,这样做就行Antd 从 V4 升级到 V5 我们可能会遇
前言
这个问题常常出现在类似业务技术栈统一需要将 Antd 版本升级到 V5 。
Antd 从 V4 升级到 V5 我们可能会遇到需要将antd时间组件用 moment 替换 dayjs。
Github仓库地址:
momentjs: github.com/moment/mome…
dayjs: github.com/iamkun/dayj…
Antd 的 V4 版本 时间组件 使用的是 moment.js,V5 替换为 day.js,优劣不评价,当然 dayjs 是更小一点,也有不少同学可能在 V4 版本就使用了 dayjs,那你一定知道怎么在 V4 中使用 dayjs 适配时间组件。
但还有部分同学可能在 V4 中大量使用了 moment.js 的方法,现在要升级到 V5,就不得不看一下怎么用 moment.js 来适配底层使用 dayjs 的 antd V5 了。
我们可以仿造 v4 将 momentjs 替换 dayjs 的方法,其实这个方法在官网的文档中也有提到,但是可能官网放的位置并不醒目,在一个很小的位置需要跳转才能达到。
本文主要将这部分提出来说明一下,为没有进行过这方面尝试的同学提供一下示例,同时再提一些在升级过程遇到的问题怎么解决。
WebPack 配置
如果你使用 webpack 打包,那你可以试试这个插件,@ant-design/moment-webpack-plugin
,安装相关 npm 包,在 webpack 配置中加入如下 Plugin
const AntdMomentWebpackPlugin = require('@ant-design/moment-webpack-plugin');
module.exports = {
plugins: [new AntdMomentWebpackPlugin()],
};
自定义组件
DatePicker
我们不要再使用 import { DatePicker } from 'antd';
直接引入 antd 的时间组件。
首先使用 npm 安装 rc-picker
, 然后可以在你的 common,或者 components 文件夹等你们存放公共组件的地方新建一个 MyDatePicker.jsx
,编写如下代码,然后在使用的地方从这里 import 就好了:
// js
import { DatePicker } from 'antd';
import momentGenerateConfig from 'rc-picker/lib/generate/moment';
const MyDatePicker = DatePicker.generatePicker(momentGenerateConfig);
export default MyDatePicker;
// ts
import { DatePicker } from 'antd';
import type { Moment } from 'moment';
import momentGenerateConfig from 'rc-picker/lib/generate/moment';
const MyDatePicker = DatePicker.generatePicker<Moment>(momentGenerateConfig);
export default MyDatePicker;
Calendar
类似的,新建 MyCalendar.jsx
:
//js
import { Calendar } from 'antd';
import momentGenerateConfig from 'rc-picker/es/generate/moment';
const MyCalendar = Calendar.generateCalendar(momentGenerateConfig);
export default MyCalendar;
//ts
import { Calendar } from 'antd';
import type { Moment } from 'moment';
import momentGenerateConfig from 'rc-picker/es/generate/moment';
const MyCalendar = Calendar.generateCalendar<Moment>(momentGenerateConfig);
export default MyCalendar;
TimePicker
同理,使用 timepicker 你可以新建一个 MyTimepicker.jsx
,写入如下代码:
// js
import * as React from 'react';
import DatePicker from './DatePicker';
const MyTimePicker = React.forwardRef((props, ref) => (
<DatePicker {...props} picker="time" mode={undefined} ref={ref} />
));
MyTimePicker.displayName = 'MyTimePicker';
export default MyTimePicker;
// ts
import * as React from 'react';
import type { PickerTimeProps } from 'antd/es/date-picker/generatePicker';
import type { Moment } from 'moment';
import DatePicker from './DatePicker';
export interface TimePickerProps extends Omit<PickerTimeProps<Moment>, 'picker'> {}
const MyTimePicker = React.forwardRef<any, TimePickerProps>((props, ref) => (
<DatePicker {...props} picker="time" mode={undefined} ref={ref} />
));
MyTimePicker.displayName = 'MyTimePicker';
export default MyTimePicker;
替换后时间组件部分或全部展示英文
你可以尝试以下办法:
- 使用 ConfigProvider 包裹 App 组件,利用 Antd 的 config 组件设置国际化功能,并同时在项目入口 APP 引入 momentjs 的语言包并引入中文语言包,当然你要做国际化适配的时候,在这里设置一个 state 更改引入的 Lang 就好
import React from 'react';
import { createRoot } from 'react-dom/client';
import antLang from 'antd/locale/zh_CN';
import 'moment/dist/locale/zh-cn'; // 引入moment中文语言包
// ... 引入你需要的包
import { ConfigProvider } from 'antd';
import { legacyLogicalPropertiesTransformer, StyleProvider } from '@ant-design/cssinjs';
const App = () => {
return (
<BrowserRouter>
<ConfigProvider locale={antLang}>
{/* 这里替换你的Router组件 */}
<PageRouter />
</ConfigProvider>
</BrowserRouter>
);
};
const root = createRoot(document.getElementById('root'));
root.render(<App />);
2. 一般来说如果你的组件层级关系正确,到这里问题就解决了,但是如果你有一些地方的组件没有生效,你可以在你的时间组件中(如刚才的 MyDatePicker.jsx)
加入这段代码,设置时间组件的 locale 并引入 moment 语言包
import { DatePicker } from 'antd';
import momentGenerateConfig from 'rc-picker/lib/generate/moment';
import antLang from 'antd/lib/date-picker/locale/zh_CN';
import 'moment/dist/locale/zh-cn';
const MomentDatePicker = DatePicker.generatePicker(momentGenerateConfig);
const MyDatePicker = () => {
return (
<MomentDatePicker
{/* 其他你要设置的内容 */}
locale={antLang}
/>
)
}
export default MyDatePicker;
Onchange 和 OnCalendarChange
在 V4 版本中,可能有人错误的同时设置了这两个回调方法,升级到 v5 后发现只要一打开时间组件时间就疯狂乱跳。我想想说的其他这两个方法本就不该同时设置,我们可以根据需求选择在一个回调函数中完成业务逻辑。
import { DatePicker } from 'antd';
import momentGenerateConfig from 'rc-picker/lib/generate/moment';
import antLang from 'antd/lib/date-picker/locale/zh_CN';
import 'moment/dist/locale/zh-cn';
const MomentDatePicker = DatePicker.generatePicker(momentGenerateConfig);
const MyDatePicker = () => {
return (
<MomentDatePicker
{/* 其他你要设置的内容 */}
{/* 以下二选一 */}
onCalendarChange={(val) => {
// ...
}}
onChange={
// ...
}
/>
)
}
export default MyDatePicker;
转载自:https://juejin.cn/post/7426558944104464420