三、核心功能详解
3.1 列管理
3.1.1 列宽调整
用户可以通过拖拽列边框来调整列宽。如果需要程序化调整,可以设置 resizable 属性控制某列是否允许用户调整宽度。
// 禁止用户调整某列宽度
const columns: GridColDef[] = [
{ field: 'name', headerName: '姓名', width: 150, resizable: false },
{ field: 'age', headerName: '年龄', width: 100, type: 'number' },
];
// 双击列边框自动适配内容宽度
<DataGrid
autosizeOptions={
{
includeHeaders: true, // 是否包含表头宽度
includeOutliers: true, // 是否考虑异常值
outliersFactor: 1.5 // 异常值因子
}}
onAutosize={handleAutosize}
/>
列宽配置的最佳实践:
为关键列(如 ID、操作列)设置固定宽度,为内容列(如描述、备注)使用 flex 弹性布局。
使用 minWidth 和 maxWidth 限制列宽范围,避免过窄或过宽影响体验。
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', width: 80, minWidth: 60, maxWidth: 120 },
{ field: 'name', headerName: '姓名', flex: 1, minWidth: 120 },
{ field: 'description', headerName: '描述', flex: 2, minWidth: 200 },
];
3.1.2 列重新排序
此功能属于 Pro 及以上版本。
用户可以通过拖拽列表头来调整列的显示顺序,这在需要用户自定义视图的场景下非常有用。
import { DataGridPro } from '@mui/x-data-grid-pro';
const [columnReorderModel, setColumnReorderModel] = useState(['id', 'name', 'age', 'city']);
<DataGridPro
columnReorderModel={columnReorderModel}
onColumnReorder={setColumnReorderModel}
/>
3.1.3 列固定(Pinning)
此功能属于 Pro 及以上版本。
将某些关键列(如“操作”列、ID 列)固定在左侧或右侧,避免在横向滚动时被移出视野,提升大数据表格的可读性。
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', pinned: 'left', width: 80 }, // 固定在左侧
{ field: 'name', headerName: '姓名', width: 150 },
{ field: 'age', headerName: '年龄', width: 100 },
{ field: 'city', headerName: '城市', width: 120 },
{ field: 'actions', headerName: '操作', pinned: 'right', width: 120 }, // 固定在右侧
];
固定列的限制:固定列的数量会影响性能,建议将固定列的数量控制在合理范围内(通常不超过 2-3 列)。
3.1.4 列分组
将多个相关列归为一组,在表头显示分组标题,提升表格的语义化和可读性。
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{
headerName: '基本信息',
children: [
{ field: 'name', headerName: '姓名', width: 150 },
{ field: 'gender', headerName: '性别', width: 80 },
{ field: 'birthDate', headerName: '出生日期', width: 120, type: 'date' },
],
},
{
headerName: '联系信息',
children: [
{ field: 'phone', headerName: '电话', width: 130 },
{ field: 'email', headerName: '邮箱', width: 200 },
],
},
];
3.2 行管理
3.2.1 行高
支持调整固定行高,也支持根据内容自动撑开行高。
// 固定高度(性能最佳)
<DataGrid rowHeight={60} />
// 自动高度(根据内容自动调整,但会影响虚拟化性能)
<DataGrid getRowHeight={() => 'auto'} />
// 根据内容动态计算高度(更精细的控制,但性能开销更大)
<DataGrid getRowHeight={({ model, index }) => {
// model 是行数据,index 是行索引
const contentLength = model.description?.length || 0;
return Math.min(200, Math.max(60, Math.ceil(contentLength / 50) * 24));
}} />
性能提示:固定行高(rowHeight)的性能最佳,因为它允许虚拟化引擎精确计算可视区域。使用动态行高时,Data Grid 需要额外计算每行的高度,会带来一定的性能开销。
3.2.2 行排序
支持单列排序(社区版)和多列排序(Pro 及以上版本)。
// 单列排序(社区版)
const [sortModel, setSortModel] = useState([]);
<DataGrid
sortModel={sortModel}
onSortModelChange={setSortModel}
/>
// 多列排序(Pro 版),用户在 UI 上按住 Ctrl 键选择多个排序字段
<DataGridPro
sortModel={sortModel}
onSortModelChange={setSortModel}
/>
自定义排序逻辑:
const columns: GridColDef[] = [
{
field: 'status',
headerName: '状态',
sortComparator: (v1, v2, param1, param2) => {
// 自定义排序:将状态按优先级排序(待处理 > 处理中 > 已完成)
const priority = { 'pending': 3, 'processing': 2, 'completed': 1 };
return priority[v1] - priority[v2];
}
},
];
3.2.3 行筛选
Data Grid 提供了三种筛选方式,适应不同的使用场景:
1.列筛选(Column Filters)
通过点击列表头筛选图标,配置该列的筛选条件。支持文本、数字、日期等多种筛选类型。
const [filterModel, setFilterModel] = useState({
items: [
{ field: 'name', operator: 'contains', value: '张' },
{ field: 'age', operator: '>=', value: 18 },
],
});
<DataGrid
filterModel={filterModel}
onFilterModelChange={setFilterModel}
/>

2.快速筛选(Quick Filter)
提供一个全局的搜索框,在所有文本列中进行全文搜索。非常适合需要快速查找数据的场景。
import { DataGrid, GridToolbarQuickFilter } from '@mui/x-data-grid';
// 自定义工具栏,包含快速筛选输入框
function CustomToolbar() {
return (
<div style={
{ padding: '8px' }}>
<GridToolbarQuickFilter />
</div>
);
}
<DataGrid
components={
{ Toolbar: CustomToolbar }}
initialState={
{
filter: {
filterModel: {
items: [],
quickFilterValues: ['search keyword'],
},
},
}}
/>
3.表头筛选(Header Filters)
在列表头下方直接显示筛选输入框,适合高频筛选的场景。此功能属于 Pro 及以上版本。
<DataGridPro
headerFilters
headerFilterHeight={50}
/>
3.3 分页
Data Grid 支持客户端分页和服务端分页两种模式。
客户端分页:一次性加载所有数据,在前端进行分页。适用于数据量不大的场景。
import { DataGrid, gridPageCountSelector, GridPagination, useGridApiContext, useGridSelector } from '@mui/x-data-grid';
function CustomPagination() {
const apiRef = useGridApiContext();
const pageCount = useGridSelector(apiRef, gridPageCountSelector);
return (
<Pagination
count={pageCount}
page={page + 1}
onChange={(event, value) => apiRef.current.setPage(value - 1)}
/>
);
}
<DataGrid
rows={rows}
columns={columns}
pagination
pageSize={10}
rowsPerPageOptions={[5, 10, 25, 50]}
components={
{ Pagination: CustomPagination }}
/>
服务端分页:每次只请求当前页的数据,适用于海量数据的场景。
<DataGrid
rows={rows}
columns={columns}
pagination
paginationMode="server"
rowCount={totalCount}
page={page}
pageSize={pageSize}
onPageChange={(newPage) => setPage(newPage)}
onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
loading={loading}
/>
3.4 数据量优化与性能
3.4.1 DOM 虚拟化
Data Grid 高性能的核心秘密就是 DOM 虚拟化。无论表格实际有多少行,它只会渲染当前视口可见的 DOM 节点(加上适量的缓冲区),在滚动时动态替换内容。这使得它能够轻松处理数万行数据而不会让浏览器卡死。
import { DataGridPro } from '@mui/x-data-grid-pro';
// Pro 版本解除了社区版 100 行的限制,利用虚拟化支持大数据量
<DataGridPro rows={largeDataset} columns={columns} />
虚拟化的工作原理:
Data Grid 创建一个固定高度的滚动容器
根据滚动位置计算应该显示哪些行和列
只渲染这些行和列对应的 DOM 元素
当用户滚动时,移除超出视口的元素,动态添加新进入视口的元素
这种机制使得 DOM 节点数量始终保持稳定(通常只有几十个),无论数据量多大。
行虚拟化:垂直滚动时长列表的渲染机制。社区版支持行虚拟化,但限制在 100 行以内;Pro 及以上版本则移除了该限制。
列虚拟化:水平滚动时,只渲染当前可见的列。默认情况下,视口外 150px 的列会被卸载,可以通过 columnBufferPx 属性调整缓冲区大小。该功能对所有版本均默认开启。
// 调整列缓冲区,让视口外渲染更多列,以减少快速滚动时空白闪烁
<DataGrid columnBufferPx={300} />
3.4.2 禁用虚拟化
在测试环境(如 jsdom)中,虚拟化可能会导致测试不稳定。可以使用 disableVirtualization 强制关闭虚拟化。
<DataGrid rows={rows} columns={columns} disableVirtualization />
⚠️ 警告:禁用虚拟化会导致所有行和列全部渲染到 DOM 中,数据量较大时会导致严重的性能问题,仅推荐在测试环境或小数据量场景使用。
3.5 数据编辑
Data Grid 支持行编辑、单元格编辑和全行编辑等多种编辑模式。
3.5.1 基础编辑
<DataGrid
rows={rows}
columns={columns}
editMode="cell" // 单元格编辑模式(点击单元格进入编辑)
// editMode="row" // 行编辑模式
onCellEditStart={handleCellEditStart}
onCellEditStop={handleCellEditStop}
onCellEditCommit={handleCellEditCommit}
/>
3.5.2 自定义编辑器
可以为特定列配置自定义的编辑器组件:
const columns: GridColDef[] = [
{
field: 'status',
headerName: '状态',
editable: true,
type: 'singleSelect',
valueOptions: ['待处理', '处理中', '已完成'],
},
{
field: 'rating',
headerName: '评分',
editable: true,
renderEditCell: (params) => (
<Select
value={params.value}
onChange={(e) => params.api.setEditCellValue(params.id, params.field, e.target.value)}
>
<MenuItem value={1}>⭐</MenuItem>
<MenuItem value={2}>⭐⭐</MenuItem>
<MenuItem value={3}>⭐⭐⭐</MenuItem>
<MenuItem value={4}>⭐⭐⭐⭐</MenuItem>
<MenuItem value={5}>⭐⭐⭐⭐⭐</MenuItem>
</Select>
),
},
];
3.5.3 行编辑控制
可以通过条件控制哪些行可以编辑:
<DataGrid
isCellEditable={(params) => {
// 只有状态为待处理的行可以编辑
return params.row.status === '待处理';
}}
/>
3.6 数据导出
3.6.1 导出为 CSV
社区版及以上均默认支持导出 CSV 文件。Data Grid 提供了内置的工具栏组件,包含导出按钮。
import { DataGrid, GridToolbar } from '@mui/x-data-grid';
<DataGrid
rows={rows}
columns={columns}
components={
{ Toolbar: GridToolbar }}
componentsProps={
{
toolbar: {
showQuickFilter: true,
printOptions: { disableToolbarButton: true },
csvOptions: {
fileName: '数据导出',
delimiter: ',',
utf8WithBom: true,
},
},
}}
/>
3.6.2 导出为 Excel(Premium 专属)
Premium 版本支持将数据导出为 .xlsx 格式,且在最新版本中对图表集成和导出体验进行了优化。
<DataGridPremium
toolbar={
{ excel: true, csv: true }}
excelOptions={
{
fileName: 'export.xlsx',
sheetName: 'Sheet1',
}}
/>
3.6.3 剪贴板操作
复制:支持选中单元格或行后通过快捷键(Ctrl+C)复制数据。Premium 版本还支持复制包含表头的数据。
粘贴:Premium 版本支持从 Excel 或其它表格粘贴数据到 Data Grid 中,支持大容量数据粘贴和智能数据解析。
<DataGridPremium
clipboardCopy
clipboardCopySelectionEnabled
onClipboardCopy={(copiedData) => console.log('Copied:', copiedData)}
/>