likes
comments
collection
share

AntdV4升级到V5,时间组件momentjs替换dayjs,这样做就行Antd 从 V4 升级到 V5 我们可能会遇

作者站长头像
站长
· 阅读数 40

前言

这个问题常常出现在类似业务技术栈统一需要将 Antd 版本升级到 V5 。

Antd 从 V4 升级到 V5 我们可能会遇到需要将antd时间组件用 moment 替换 dayjs。

Github仓库地址:

momentjs: github.com/moment/mome…

dayjs: github.com/iamkun/dayj…

AntdV4升级到V5,时间组件momentjs替换dayjs,这样做就行Antd 从 V4 升级到 V5 我们可能会遇

AntdV4升级到V5,时间组件momentjs替换dayjs,这样做就行Antd 从 V4 升级到 V5 我们可能会遇

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;

替换后时间组件部分或全部展示英文

你可以尝试以下办法:

  1. 使用 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
评论
请登录