跳到内容
+

从 v4 迁移到 v5

本指南介绍将数据表格从 v4 迁移到 v5 所需的更改。

简介

本参考指南旨在帮助您将站点从 MUI X v4 升级到 v5。MUI X v5 完全兼容 Material UI v5 和 MUI System v5,并且可以通过一些额外的步骤与 Material UI v4 和 MUI System v4 一起使用。大多数重大更改都是 CSS 类或变量的重命名,以提高数据表格的一致性。

从 v4 迁移 MUI Core

将 MUI Core v4 与 v5 一起使用

通过以下步骤可以实现将 Material UI v4 与 v5 一起使用

  1. 首先,确保您已安装 Material UI v5。如果未安装,请按照这些说明进行安装。
  2. 添加自定义的createGenerateClassName以禁用 JSS 中全局类名的生成。
import { createGenerateClassName } from '@material-ui/core/styles';

const generateClassName = createGenerateClassName({
  // By enabling this option, if you have non-MUI elements (for example `<div />`)
  // using MUI classes (for example `.MuiButton`) they will lose styles.
  // Make sure to convert them to use `styled()` or `<Box />` first.
  disableGlobal: true,
  // Class names will receive this seed to avoid name collisions.
  seed: 'mui-jss',
});
  1. 创建一个 v5 主题,其自定义设置与 v4 主题相同。这必须这样做,因为主题在不同的 Material UI 版本之间不共享。
import { createMuiTheme as createThemeV4 } from '@material-ui/core/styles';
import { createTheme as createThemeV5 } from '@mui/material/styles';

const themeV4 = createThemeV4({
  palette: {
    primary: {
      main: '#2196f3',
    },
  },
});

const themeV5 = createThemeV5({
  palette: {
    primary: {
      main: themeV4.palette.primary.main,
    },
  },
});
  1. 将类名生成器和 v5 主题应用于应用程序。
import * as React from 'react';
import { ThemeProvider as ThemeProviderV5 } from '@mui/material/styles';
import { ThemeProvider as ThemeProviderV4, StylesProvider } from '@material-ui/core/styles';

const generateClassName = createGenerateClassName({ ... });
const themeV4 = createThemeV4({ ... });
const themeV5 = createThemeV5({ ... });

export default function DataGridDemo() {
  return (
    <StylesProvider generateClassName={generateClassName}>
      <ThemeProviderV4 theme={themeV4}>
        <ThemeProviderV5 theme={themeV5}>
          {/* Your component tree. */}
        </ThemeProviderV5>
      </ThemeProviderV4>
    </StylesProvider>
  );
}

完成! 现在,您可以渲染任何依赖于 Material UI v5 的依赖项,而无需从 v4 升级,它们将无缝地并行运行。例如,以下交互式演示展示了这些步骤如何与数据表格结合使用

迁移 MUI X

更新 MUI X 版本

要使用 v5 版本的 MUI X,您首先需要更新到新的包名称

  • @material-ui/data-grid 现在是 @mui/x-data-grid (MIT)
  • @material-ui/x-grid 现在是 @mui/x-data-grid-pro (商业版)

CSS 类

  • 一些 CSS 类被删除或重命名

    MUI X v4 类 MUI X v5 类
    .MuiDataGrid-window 已删除
    .MuiDataGrid-windowContainer 已删除
    .MuiDataGrid-viewport .MuiDataGrid-virtualScroller
    .MuiDataGrid-dataContainer .MuiDataGrid-virtualScrollerContent
    .MuiDataGrid-renderingZone .MuiDataGrid-virtualScrollerRenderZone
    .MuiDataGrid-gridMenuList .MuiDataGrid-menuList
    .MuiGridToolbarContainer-root .MuiDataGrid-toolbarContainer
    .MuiGridMenu-root .MuiDataGrid-menu
    .MuiDataGridColumnsPanel-root .MuiDataGrid-columnsPanel
    .MuiGridPanel-root .MuiDataGrid-panel
    .MuiGridPanelContent-root .MuiDataGrid-panelContent
    .MuiGridPanelFooter-root .MuiDataGrid-panelFooter
    .MuiDataGridPanelHeader-root .MuiDataGrid-panelHeader
    .MuiGridPanelWrapper-root .MuiDataGrid-panelWrapper
    .MuiGridFilterForm-root .MuiDataGrid-filterForm
    .MuiGridToolbarFilterButton-root .MuiDataGrid-toolbarFilterList

模块增强

  • 模块增强不再默认启用。此更改是为了防止与同时使用数据表格和数据表格 Pro 的项目发生冲突。

    为了仍然能够在主题级别进行覆盖,请将以下导入添加到您的项目中

    +import type {} from '@mui/x-data-grid/themeAugmentation';
    +import type {} from '@mui/x-data-grid-pro/themeAugmentation';
    

虚拟化

  • onViewportRowsChange 属性和 viewportRowsChange 事件已被删除

    您可以使用 rowsScroll 事件的监听器来替换它们

    const apiRef = useGridApiRef();
    const prevRenderContext = React.useRef(null);
    
    React.useEffect(() => {
      return apiRef.current.subscribeEvent('rowsScroll', ({ renderContext }) => {
        if (
          !prevRenderContext.current ||
          renderContext.firstRowIdx !== prevRenderContext.current.firstRowIndex ||
          renderContext.lastRowIdx !== prevRenderContext.current.lastRowIndex
        ) {
          prevRenderContext.current = renderContext;
          const params = {
            firstRowIndex: renderContext.firstRowIndex,
            lastRowIndex: renderContext.lastRowIndex,
          };
        }
      });
    }, [apiRef]);
    
    <DataGridPro apiRef={apiRef} />;
    

已删除的属性

  • 为了提高性能,从 GridCellGridRow 中删除了一些事件监听器和 DOM 属性。

    以下属性已被删除。

    • onCellBlur
    • onCellOver
    • onCellOut
    • onCellEnter
    • onCellLeave
    • onRowOver
    • onRowOut
    • onRowEnter
    • onRowLeave

    如果您依赖于它们,则可以使用 componentsProps.rowcomponentsProps.cell 将自定义属性传递给行或单元格。有关更多信息,请查看此页面。示例

    -<DataGrid onRowOver={handleRowOver} />;
    +<DataGrid
    +  componentsProps={{
    +    row: { onMouseOver: handleRowOver },
    +  }}
    +/>;
    

    data-rowindexdata-rowselected 属性已从单元格元素中删除。等效属性可以在行元素中找到。

    data-editable 属性已从单元格元素中删除。使用 .MuiDataGrid-cell--editable CSS 类。

    data-mode 属性已从单元格元素中删除。使用 .MuiDataGrid-cell--editing CSS 类。

状态访问

  • 状态直接访问不再被视为公共 API 的一部分。我们仅保证选择器在次要版本之间继续工作。我们建议您避免直接访问状态子键,而是尽可能使用可用的选择器或 apiRef 方法。您可以使用其匹配的选择器替换以下状态访问

    直接状态访问 选择器
    state.rows gridRowsStateSelector
    state.filter gridFilterStateSelector
    state.sorting gridSortingStateSelector
    state.editRows gridEditRowsStateSelector
    state.pagination gridPaginationSelector
    state.columns gridColumnsSelector
    state.columnMenu gridColumnMenuSelector
    state.focus gridFocusStateSelector
    state.tabIndex gridTabIndexStateSelector
    state.selection gridSelectionStateSelector
    state.preferencePanel gridPreferencePanelStateSelector
    state.density gridDensitySelector
    state.columnReorder gridColumnReorderSelector
    state.columnResize gridColumnResizeSelector
  • apiRef.current.getState 方法已被删除。您可以直接通过 apiRef.current.state 访问状态

    -const state = apiRef.current.getState();
    +const state = apiRef.current.state
    
     const filterModel = gridFilterModelSelector(state);
    
  • state 属性无法正常工作,已被删除。您可以使用新的 initialState 属性代替。

    请注意,initialState 仅允许 preferencePanelfilter.filterModelsort.sortModel 键。要完全控制状态,请使用该功能的 model 属性和更改回调(例如 filterModelonFilterModelChange)。

     <DataGrid
    -  state={{
    +  initialState={{
         preferencePanel: {
           open: true,
           openedPanelValue: GridPreferencePanelsValue.filters,
         },
       }}
     />
    
  • 一些选择器已重命名以符合我们的命名约定

    MUI X v4 选择器 MUI X v5 选择器
    unorderedGridRowIdsSelector gridRowIdsSelector
    sortingGridStateSelector gridSortingStateSelector
    sortedGridRowIdsSelector gridSortedRowIdsSelector
    filterGridStateSelector gridFilterModelSelector
    visibleSortedGridRowIdsSelector gridVisibleSortedRowIdsSelector
    visibleGridRowCountSelector gridVisibleRowCountSelector
    filterGridColumnLookupSelector gridFilterActiveItemsLookupSelector
    densitySelector gridDensitySelector
  • 一些选择器已被删除/重新设计

    1. sortedGridRowsSelector 已被删除。您可以使用 gridSortedRowEntriesSelector 代替。

    返回格式已更改

    -sortedGridRowsSelector: (state: GridState) => Map<GridRowId, GridRowModel>
    +gridSortedRowEntriesSelector: (state: GridState) => GridRowEntry[]
    

    如果您需要旧格式,可以按如下方式转换选择器返回值

    -const map = sortedGridRowsSelector(state);
    +const map = new Map(gridSortedRowEntriesSelector(state).map(row => [row.id, row.model]));
    
    1. filterGridItemsCounterSelector 已被删除。您可以使用 gridFilterActiveItemsSelector
    -const filterCount = filterGridItemsCounterSelector(state);
    +const filterCount = gridFilterActiveItemsSelector(state).length;
    
    1. unorderedGridRowModelsSelector 已被删除。您可以使用 apiRef.current.getRowModelsgridRowIdsSelectorgridRowsLookupSelector
    -const rowModels = unorderedGridRowModelsSelector(apiRef.current.state);
    
     // using the `apiRef`
    +const rowModels = apiRef.current.getRowModels();
    
     // using selectors
    +const allRows = gridRowIdsSelector(apiRef.current.state);
    +const idRowsLookup = gridRowsLookupSelector(apiRef.current.state);
    +const rowModels = new Map(allRows.map((id) => [id, idRowsLookup[id]]));
    
    1. visibleSortedGridRowsSelector 已被删除。您可以使用 gridVisibleSortedRowEntriesSelector

    返回格式已更改

    -visibleSortedGridRowsSelector: (state: GridState) => Map<GridRowId, GridRowModel>;
    +gridVisibleSortedRowEntriesSelector: (state: GridState) => GridRowEntry[];
    

    如果您需要旧格式,可以按如下方式转换选择器返回值

    -const map = visibleSortedGridRowsSelector(state);
    +const map = new Map(gridVisibleSortedRowEntriesSelector(state).map(row => [row.id, row.model]));
    
    1. visibleSortedGridRowsAsArraySelector 已被删除。您可以使用 gridVisibleSortedRowEntriesSelector

    返回格式已更改

    -visibleSortedGridRowsAsArraySelector: (state: GridState) => [GridRowId, GridRowData][];
    +gridVisibleSortedRowEntriesSelector: (state: GridState) => GridRowEntry[];
    

    如果您需要旧格式,可以按如下方式转换选择器返回值

    -const rows = visibleSortedGridRowsAsArraySelector(state);
    +const rows = gridVisibleSortedRowEntriesSelector(state).map(row => [row.id, row.model]);
    

apiRef 方法

  • 用于部分更新过滤器模型的 apiRef 方法已重命名

    1. apiRef.current.applyFilterLinkOperator 已重命名为 apiRef.current.setFilterLinkOperator
    2. apiRef.current.upsertFilter 已重命名为 apiRef.current.upsertFilterItem
    3. apiRef.current.deleteFilter 已重命名为 apiRef.current.deleteFilterItem
  • 为了与其他选择 API 保持一致,apiRef.current.selectRow 中的第三个参数现在已反转。

    如果您之前传递 allowMultiple: true,则现在应传递 resetSelection: false 或停止传递任何内容。

    如果您之前传递 allowMultiple: false 或未在 allowMultiple 上传递任何内容,则现在应传递 resetSelection: true

    -selectRow: (id: GridRowId, isSelected?: boolean, allowMultiple?: boolean = false) => void;
    +selectRow: (id: GridRowId, isSelected?: boolean, resetSelection?: boolean = false) => void;
    

  • 传递给 valueFormatter 的参数已更改。

    您可以使用 api 获取缺少的参数。GridValueFormatterParams 接口现在具有以下签名

    -export type GridValueFormatterParams = Omit<GridRenderCellParams, 'formattedValue' | 'isEditable'>;
    +export interface GridValueFormatterParams {
    +  /**
    +   * The column field of the cell that triggered the event.
    +   */
    +  field: string;
    +  /**
    +   * The cell value, but if the column has valueGetter, use getValue.
    +   */
    +  value: GridCellValue;
    +  /**
    +   * GridApi that lets you manipulate the Data Grid.
    +   */
    +  api: any;
    +}
    

其他导出

  • gridCheckboxSelectionColDef 已重命名为 GRID_CHECKBOX_SELECTION_COL_DEF

  • 已删除单个字符串常量,而改用单个 gridClasses 对象

    -const columnHeaderClass = GRID_COLUMN_HEADER_CSS_CLASS;
    +const columnHeaderClass = gridClasses.columnHeader;
    
    -const rowClass = GRID_ROW_CSS_CLASS;
    +const rowClass = gridClasses.row;
    
    -const cellClass = GRID_CELL_CSS_CLASS;
    +const cellClass = gridClasses.cell;
    
    -const columnSeparatorClass = GRID_COLUMN_HEADER_SEPARATOR_RESIZABLE_CSS_CLASS;
    +const columnSeparatorClass = gridClasses['columnSeparator--resizable'];
    
    -const columnHeaderTitleClass = GRID_COLUMN_HEADER_TITLE_CSS_CLASS;
    +const columnHeaderTitleClass = gridClasses.columnHeaderTitle;
    
    -const columnHeaderDropZoneClass = GRID_COLUMN_HEADER_DROP_ZONE_CSS_CLASS;
    +const columnHeaderDropZoneClass = gridClasses.columnHeaderDropZone;
    
    -const columnHeaderDraggingClass = GRID_COLUMN_HEADER_DRAGGING_CSS_CLASS;
    +const columnHeaderDraggingClass = gridClasses['columnHeader--dragging'];
    
  • 引用列类型的常量已被删除。它们的值可以硬编码。

    -const isColumnString = column.type === GRID_STRING_COLUMN_TYPE;
    +const isColumnString = col.type === 'string';
    
    -const isColumnNumber = col.type === GRID_NUMBER_COLUMN_TYPE;
    +const isColumnNumber = col.type === 'number';
    
    -const isColumnDate = col.type === GRID_DATE_COLUMN_TYPE;
    +const isColumnDate = col.type === 'date';
    
    -const isColumnDateTime = col.type === GRID_DATETIME_COLUMN_TYPE;
    +const isColumnDateTime = col.type === 'dateTime';
    
    -const isColumnBoolean = col.type === GRID_BOOLEAN_COLUMN_TYPE;
    +const isColumnBoolean = col.type === 'boolean';
    
  • 钩子 useGridSlotComponentProps 已被删除。您可以使用以下钩子访问相同的数据。

    -const { apiRef, state, rootElement, options } = useGridSlotComponentProps();
    +const apiRef = useGridApiContext();
    +const [state] = useGridState(apiRef);
    +const rootElement = apiRef.current.rootElementRef;
    +const rootProps = useGridRootProps(); // equivalent of `options`
    

从公共 API 中删除

我们通过在某些 API 方法/选择器上添加 unstable_ 前缀,将其从我们认为的公共 API 中删除。如果您愿意,可以继续使用这些方法,但它们将来可能会在没有事先通知的情况下进行重大更改。

  1. apiRef.current.applyFilters 已重命名为 apiRef.current.unstable_applyFilters
  2. gridContainerSizesSelector 已重命名为 unstable_gridContainerSizesSelector
  3. gridViewportSizesSelector 已重命名为 unstable_gridViewportSizesSelector
  4. gridScrollBarSizeSelector 已重命名为 unstable_gridScrollBarSizeSelector