跳到内容
+

升级到 v7

本指南解释了如何从 Material UI v6 升级到 v7。

为什么您应该升级到 Material UI v7

改进的 ESM 支持

包布局已更新,现在通过 package.json 中的 exports 字段明确支持有效的 ESM 和 CommonJS。您可以在 Node.js 文档中阅读有关包导出的更多信息。

此更新修复了 Vite 和 webpack 等流行的打包工具的几个问题,并使从 Node.js 下的 ES 模块加载 MUI 包成为可能。

生活质量改进

Material UI v7 具有其他生活质量改进,包括

  • 所有组件中插槽模式的标准化
  • 通过客户端应用程序中 StyledEngineProvider 中的 enableCssLayer 属性和 Next.js App Router 应用程序中 AppRouterCacheProvider 的 CSS 层支持
  • 删除了已弃用的 API,以减少 API 表面积并使文档更易于导航

如果您正在使用任何这些包,您还应该将其版本更新到 "7.0.0"

  • @mui/icons-material
  • @mui/system
  • @mui/lab
  • @mui/material-nextjs
  • @mui/styled-engine
  • @mui/styled-engine-sc
  • @mui/utils

请注意,MUI X 包遵循与 Material UI 相同的版本控制策略。如果您正在使用以下任何包,则在升级过程中它们应保持不变

  • @mui/x-data-grid
  • @mui/x-data-grid-pro
  • @mui/x-data-grid-premium
  • @mui/x-date-pickers
  • @mui/x-date-pickers-pro
  • @mui/x-charts
  • @mui/x-tree-view
  • @mui/x-tree-view-pro

支持的浏览器和版本

最低 React 版本

React 的最低支持版本为 v17.0.0(与 v6 相同)。如果您想升级 React,建议先完成 Material UI 的升级,然后再升级 React。

最低 TypeScript 版本

TypeScript 的最低支持版本已从 v4.7 增加到 4.9。

对于 @types/react* 包,请确保它们与您正在使用的 react 的主版本相同。如果需要,请使用下面的代码片段更新您的项目(将 <version> 替换为您正在使用的 react 的主版本)

npm install @types/react@<version> @types/react-dom@<version>

重大更改

由于 v7 是一个新的主要版本,因此它包含一些影响公共 API 的更改。下面介绍了从 Material UI v6 迁移到 v7 需要采取的步骤。

包布局已更新

包布局已更新为使用 Node.js exports 字段。这带来了一些变化

不再允许超过一级的深度导入。例如

- import createTheme from '@mui/material/styles/createTheme';
+ import { createTheme } from '@mui/material/styles';

这从未得到官方支持,但现在将受到打包工具和运行时的限制。

要使用现代捆绑包(不包括对较小捆绑包大小的旧版浏览器支持),您需要配置您的打包工具以使用“mui-modern”导出条件

// webpack.config.js
{
  resolve: {
    conditionNames: ['mui-modern', '...'],
  }
}

// vite.config.js
{
  resolve: {
    conditions: ['mui-modern', 'module', 'browser', 'development|production']
  }
}

如果您使用 Vite 别名来强制图标包的 ESM 导入,则应将其删除,因为它不再必要

 // vite.config.js
   resolve: {
     alias: [
-      {
-        find: /^@mui\/icons-material\/(.*)/,
-        replacement: "@mui/icons-material/esm/$1",
-      },
     ],
   },

如果您正在增强主题并使用嵌套导入的声明,则应将其替换为 @mui/material/styles。您可能还必须重命名接口,因为有些接口是从 @mui/material/styles 下以不同的名称导出的

-declare module '@mui/material/styles/createTypography' {
+declare module '@mui/material/styles' {
-  interface TypographyOptions {
+  interface TypographyVariantsOptions {
     // ...
   }

-  interface Typography {
+  interface TypographyVariants {
     // ...
   }
 }

Grid 和 Grid2 已重命名

已弃用的 Grid 组件已重命名为 GridLegacyGrid2 组件已移至 Grid 命名空间。根据您的项目,您可以遵循以下方法之一

  1. 如果您正在使用已弃用的 grid 并希望升级,请运行以下代码修改

    npx @mui/codemod v7.0.0/grid-props <path/to/folder>
    

    有关更多信息,请参阅 Grid 升级指南

  2. 如果您正在使用已弃用的 grid 并希望继续使用它,请按如下方式更新 Grid 引用

     // imports
    -import Grid, { gridClasses, GridProps } from '@mui/material/Grid';
    +import Grid, { gridLegacyClasses, GridLegacyProps } from '@mui/material/GridLegacy';
    
    -import { Grid } from '@mui/material';
    +import { GridLegacy as Grid } from '@mui/material';
    
     // theme
     const theme = createTheme({
       components: {
    -    MuiGrid: {
    +    MuiGridLegacy: {
           // ...
         },
       },
     });
    
     // CSS classes
    -.MuiGrid-root
    +.MuiGridLegacy-root
    
  3. 如果您正在使用 Grid2,请按如下方式更新 Grid2 引用

     // imports
    -import Grid, { grid2Classes as gridClasses, Grid2Props as GridProps } from '@mui/material/Grid2';
    +import Grid, { gridClasses, GridProps } from '@mui/material/Grid';
    
    -import { Grid2 as Grid } from '@mui/material';
    +import { Grid } from '@mui/material';
    
     // theme
     const theme = createTheme({
       components: {
    -    MuiGrid2: {
    +    MuiGrid: {
           // ...
         },
       },
     });
    
     // CSS classes
    -.MuiGrid2-root
    +.MuiGrid-root
    

InputLabel size 属性已标准化

InputLabelsize 属性现在遵循其他组件(如 ButtonTextField)中使用的标准命名约定。'normal' 已替换为 'medium' 以保持一致性。

如果您使用 size="normal",请将其更新为 size="medium"

-<InputLabel size="normal">Label</InputLabel>
+<InputLabel size="medium">Label</InputLabel>

默认行为保持不变,因此除非您显式设置 size="normal",否则无需更新。

使用此代码修改自动更新 size

npx @mui/codemod v7.0.0/input-label-size-normal-medium <path/to/folder>

SvgIcon 的 data-testid 已删除

默认的 data-testid 属性已从生产捆绑包中 @mui/icons-material 中的图标中删除。此更改确保 data-testid 属性仅在需要时定义,从而减少命名冲突的可能性并删除生产中不必要的属性。

主题行为更改

当 CSS 主题变量启用内置的浅色和深色配色方案时,主题不再在模式之间更改。下面的代码片段演示了当用户切换深色模式时,来自 useColorSchememode 状态发生变化,但主题对象不再变化

import {
  ThemeProvider,
  createTheme,
  useTheme,
  useColorScheme,
} from '@mui/material/styles';

const theme = createTheme({
  cssVariables: {
    colorSchemeSelector: 'class',
  },
  colorSchemes: {
    light: true,
    dark: true,
  },
});
console.log(theme.palette.mode); // 'light' is the default mode

function ColorModeToggle() {
  const { setMode, mode } = useColorScheme();
  const theme = useTheme();

  React.useEffect(() => {
    console.log(mode); // logged 'light' at first render, and 'dark' after the button click
  }, [mode]);

  React.useEffect(() => {
    console.log(theme.palette.mode); // logged 'light' at first render, no log after the button click
  }, [theme]);

  return <button onClick={() => setMode('dark')}>Toggle dark mode</button>;
}

function App() {
  return (
    <ThemeProvider theme={theme}>
      <ColorModeToggle />
    </ThemeProvider>
  );
}

此默认行为是为了通过避免模式更改时不必要的重新渲染来提高性能。

建议在样式中使用 theme.vars.* 作为值,以直接引用 CSS 变量

const Custom = styled('div')(({ theme }) => ({
  color: theme.vars.palette.text.primary,
  background: theme.vars.palette.primary.main,
}));

如果您需要进行运行时计算,我们建议尽可能使用 CSS 而不是 JavaScript。例如,可以使用 color-mix 函数调整颜色的 alpha 通道

const Custom = styled('div')(({ theme }) => ({
  color: `color-mix(in srgb, ${theme.vars.palette.text.primary}, transparent 50%)`,
}));

但是,如果 CSS 方法不可行,您可以直接从 theme.colorSchemes 对象访问该值,然后应用浅色和深色样式

const Custom = styled('div')(({ theme }) => ({
  color: alpha(theme.colorSchemes.light.palette.text.primary, 0.5),
  ...theme.applyStyles('dark', {
    color: alpha(theme.colorSchemes.dark.palette.text.primary, 0.5),
  }),
}));

如果以上任何方法都不适合您的项目,您可以通过将 forceThemeRerender 属性传递给 ThemeProvider 组件来选择退出此行为

<ThemeProvider forceThemeRerender />

已删除已弃用的 API

在 v5 中已弃用的 API 已在 v7 中删除。

createMuiTheme 函数

已弃用的 createMuiTheme 函数已删除。请改用 createTheme

-import { createMuiTheme } from '@mui/material/styles';
+import { createTheme } from '@mui/material/styles';

Dialog 的 onBackdropClick 属性

已弃用的 onBackdropClick 属性已从 Dialog 组件中删除。请改用 onClose 回调,它接收事件和对话框关闭的原因。以下是如何使用它的示例

function Example() {
  const [open, setOpen] = React.useState(false);

  const handleClose = (event, reason) => {
    if (reason === 'backdropClick') {
      // Handle the backdrop click
    }
    setOpen(false);
  };

  return (
    <Dialog open={open} onClose={handleClose}>
      {/* Dialog content */}
    </Dialog>
  );
}

experimentalStyled 函数

已弃用的 experimentalStyled 函数已删除。请改用 styled

-import { experimentalStyled as styled } from '@mui/material/styles';
+import { styled } from '@mui/material/styles';

Hidden 和 PigmentHidden 组件

已弃用的 HiddenPigmentHidden 组件已删除。

使用 sx 属性替换 implementation="css"

-<Hidden implementation="css" xlUp><Paper /></Hidden>
+<Paper sx={{ display: { xl: 'none', xs: 'block' } }} />
-<Hidden implementation="css" mdDown><Paper /></Hidden>
+<Paper sx={{ display: { xs: 'none', md: 'block' } }} />

使用 useMediaQuery hook 替换 implementation="js"

-<Hidden implementation="js" xlUp><Paper /></Hidden>
+const hidden = useMediaQuery(theme => theme.breakpoints.up('xl'));
+return hidden ? null : <Paper />;

Modal 的 onBackdropClick 属性

已弃用的 onBackdropClick 属性已从 Modal 组件中删除。请改用 onClose 回调,它接收事件和模态框关闭的原因。以下是如何使用它的示例

function Example() {
  const [open, setOpen] = React.useState(false);

  const handleClose = (event, reason) => {
    if (reason === 'backdropClick') {
      // Handle the backdrop click
    }
    setOpen(false);
  };

  return (
    <Modal open={open} onClose={handleClose}>
      {/* Modal content */}
    </Modal>
  );
}

Rating 的 MuiRating-readOnly CSS 类

已弃用的 MuiRating-readOnly 类已被删除,取而代之的是 Mui-readOnly 全局类。

-.MuiRating-readOnly
+.Mui-readOnly

StepButtonIcon 类型

已弃用的 StepButtonIcon 类型已删除。请改用 StepButtonProps['icon']

- import { StepButtonIcon } from '@mui/material/StepButton';
+ import { StepButtonProps } from '@mui/material/StepButton';

-StepButtonIcon
+StepButtonProps['icon']

StyledEngineProvider 导入路径

'@mui/material' 导入 StyledEngineProvider 已被弃用,现在已被删除。请改为从 '@mui/material/styles' 导入

-import { StyledEngineProvider } from '@mui/material';
+import { StyledEngineProvider } from '@mui/material/styles';

Lab 组件已移至主包

以下 @mui/lab 组件和 hook 已移至 @mui/material

  • Alert
  • AlertTitle
  • Autocomplete
  • AvatarGroup
  • Pagination
  • PaginationItem
  • Rating
  • Skeleton
  • SpeedDial
  • SpeedDialAction
  • SpeedDialIcon
  • ToggleButton
  • ToggleButtonGroup
  • usePagination

要继续使用这些组件和 hook,请从 @mui/material 而不是 @mui/lab 导入它们。

-import Alert from '@mui/lab/Alert';
+import Alert from '@mui/material/Alert';

-import { Alert } from '@mui/lab';
+import { Alert } from '@mui/material';

使用此代码修改自动更新导入

npx @mui/codemod v7.0.0/lab-removed-components <path/to/folder>