AG Grid React 中文文档与API配置汇总
目录
简介
AG Grid是一个功能全面的JavaScript数据表格。提供了企业级功能,支持React、Angular、Vue和纯JavaScript。
版本区别
- Community版:免费开源,包含基础功能
- Enterprise版:付费版,包含高级功能(如行分组、聚合、树形数据、过滤工具栏等)
入门指南
安装
安装核心包和React组件 npm install --save ag-grid-community ag-grid-react 如需使用企业版功能 npm install --save ag-grid-enterprise
基本使用
import React, { useState, useEffect } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
function MyGrid() {
const [rowData, setRowData] = useState([]);
const columnDefs = [
{ field: 'make' },
{ field: 'model' },
{ field: 'price' }
];
useEffect(() => {
fetch('https://www.ag-grid.com/example-assets/row-data.json')
.then(result => result.json())
.then(rowData => setRowData(rowData));
}, []);
return (
<div className="ag-theme-alpine" style={{ height: 400, width: 600 }}>
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
/>
</div>
);
}
网格选项
核心配置选项
属性 | 类型 | 描述 |
---|
rowData | any[] | 显示的行数据 |
columnDefs | ColDef[] | 列定义配置 |
defaultColDef | ColDef | 所有列的默认配置 |
rowSelection | 'single' 或 'multiple' | 行选择模式 |
suppressRowClickSelection | boolean | 禁止点击行选中,默认false |
domLayout | 'normal' 或 'autoHeight' 或 'print' | 网格的DOM布局方式 |
rowHeight | number | 行高度 |
headerHeight | number | 表头高度 |
pagination | boolean | 是否启用分页 |
paginationPageSize | number | 每页行数 |
animateRows | boolean | 行排序和过滤时是否有动画效果 |
enableCellTextSelection | boolean | 是否允许选择单元格文本 |
tooltipShowDelay | number | 悬浮提示显示延迟(毫秒) |
onGridReady | function | 网格准备就绪时的回调函数 |
尺寸和响应式
属性 | 类型 | 描述 |
---|
domLayout | string | 布局类型: 'normal'(默认), 'autoHeight', 'print' |
suppressColumnVirtualisation | boolean | 禁用列虚拟化,默认false |
suppressRowVirtualisation | boolean | 禁用行虚拟化,默认false |
pivotMode | boolean | 是否启用透视模式 |
suppressAutoSize | boolean | 禁用自动调整大小,默认false |
suppressColumnMoveAnimation | boolean | 禁用列移动动画,默认false |
列定义
基本列属性
const columnDefs = [
{
field: 'athlete',
headerName: '运动员',
width: 150,
editable: true,
filter: true,
sortable: true,
resizable: true,
pinned: 'left',
hide: false,
checkboxSelection: true,
headerCheckboxSelection: true,
cellRenderer: 'myCellRenderer',
cellEditor: 'myCellEditor',
valueFormatter: (params) => {
return '$' + params.value;
},
tooltipField: 'athlete',
}
]
默认列配置
const defaultColDef = {
flex: 1,
minWidth: 100,
resizable: true,
sortable: true,
filter: true,
editable: false,
floatingFilter: true,
};
列类型(columnTypes)
const columnTypes = {
numberColumn: {
width: 130,
filter: 'agNumberColumnFilter',
valueFormatter: (params) => {
return params.value.toLocaleString();
}
},
dateColumn: {
filter: 'agDateColumnFilter',
filterParams: {
comparator: (filterLocalDateAtMidnight, cellValue) => {
// 日期比较逻辑
}
}
},
nonEditableColumn: { editable: false }
};
核心功能
行选择
<AgGridReact
rowSelection="multiple" // 'single' 或 'multiple'
suppressRowClickSelection={true} // 阻止点击行选择
rowMultiSelectWithClick={true} // 允许单击多选
rowDeselection={true} // 允许取消选择
suppressCellSelection={false} // 是否禁用单元格选择
/>
排序
<AgGridReact
sortingOrder={['asc', 'desc']} // 排序顺序
multiSortKey="ctrl" // 多列排序按键('ctrl'或'shift')
accentedSort={true} // 支持带重音符号的排序
suppressMultiSort={false} // 是否禁用多列排序
rememberGroupStateWhenNewData={true}// 记住分组状态
/>
过滤
<AgGridReact
floatingFilter={true} // 启用浮动过滤器
suppressMenuHide={true} // 不隐藏菜单
suppressFilter={false} // 不禁用过滤功能
quickFilterText={searchText} // 快速过滤文本
/>
分页
<AgGridReact
pagination={true}
paginationPageSize={10}
paginationAutoPageSize={false} // 自动计算页面大小
suppressPaginationPanel={false} // 不禁用分页面板
/>
数据管理
数据源
简单方式(直接使用rowData)
<AgGridReact rowData={rowData} />
服务器端(无限滚动)
const dataSource = {
getRows: (params) => {
const { startRow, endRow, filterModel, sortModel } = params;
fetch('api/data?start=' + startRow + '&end=' + endRow)
.then(response => response.json())
.then(data => {
params.successCallback(data.rows, data.lastRow);
})
.catch(error => {
params.failCallback();
});
}
};
<AgGridReact
rowModelType="infinite"
datasource={dataSource}
cacheBlockSize={100}
maxBlocksInCache={10}
infiniteInitialRowCount={1000}
/>
行更新
gridApi.applyTransaction({ update: [updatedRow] });
gridApi.applyTransaction({
update: updatedRows,
add: newRows,
remove: rowsToRemove
});
高级功能
行分组
<AgGridReact
groupDefaultExpanded={1} // 默认展开级别
groupDisplayType="singleColumn" // 分组显示类型
groupIncludeFooter={true} // 包含分组页脚
groupSelectsChildren={true} // 选择组时一并选择子项
rowGroupPanelShow="always" // 显示行分组面板
suppressAggFuncInHeader={true} // 禁止在标题中显示聚合函数
autoGroupColumnDef={{
headerName: '组',
minWidth: 200,
cellRendererParams: {
suppressCount: false, // 显示计数
checkbox: true // 显示复选框
}
}}
/>
列组合主要配置
const columnDefs = [
{ field: 'country', rowGroup: true, hide: true },
{ field: 'year', rowGroup: true, hide: true },
{
field: 'gold',
aggFunc: 'sum',
allowedAggFuncs: ['sum', 'min', 'max', 'count']
},
{
field: 'silver',
aggFunc: 'sum'
}
];
透视功能
<AgGridReact
pivotMode={true} // 启用透视模式
suppressAggFuncInHeader={true} // 禁止在标题中显示聚合函数
pivotPanelShow="always" // 显示透视面板
pivotColumnGroupTotals="before"// 透视列组合计位置
pivotRowTotals="before" // 透视行总计位置
/>
透视列定义
const columnDefs = [
{ field: 'country', pivot: true },
{ field: 'year', rowGroup: true },
{
field: 'gold',
aggFunc: 'sum'
}
];
树形数据(Tree Data)
<AgGridReact
treeData={true}
autoGroupColumnDef={{
headerName: '名称',
field: 'name',
cellRendererParams: {
checkbox: true
}
}}
groupDefaultExpanded={1}
getDataPath={data => data.filePath}
/>
树形数据示例
const treeData = [ { name: '文件夹1', filePath: ['文件夹1'] },
{ name: '文件1.1', filePath: ['文件夹1', '文件1.1'] },
{ name: '文件夹2', filePath: ['文件夹2'] },
{ name: '文件2.1', filePath: ['文件夹2', '文件2.1'] }
];
主从表(Master/Detail)
<AgGridReact
masterDetail={true} // 启用主从视图
detailCellRenderer="myDetailRenderer" // 详情单元格渲染器
detailRowHeight={400} // 详情行高度
detailRowAutoHeight={true} // 自动调整详情行高度
/>
单元格渲染与编辑
const columnDefs = [
{
field: 'price',
cellRenderer: params => {
return '$' + params.value;
},
cellEditor: 'agSelectCellEditor',
cellEditorParams: {
values: ['小', '中', '大']
},
editable: true
}
];
内置编辑器与渲染器
'agTextCellEditor'
'agLargeTextCellEditor'
'agSelectCellEditor'
'agPopupTextCellEditor'
'agPopupSelectCellEditor'
'agDateCellEditor'
'agCheckboxCellEditor'
'agAnimateShowChangeCellRenderer'
'agAnimateSlideCellRenderer'
'agGroupCellRenderer'
'agLoadingCellRenderer'
样式与主题
内置主题
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact ... />
</div>
可用主题
ag-theme-alpine
- 默认浅色主题
ag-theme-alpine-dark
- 暗色Alpine主题
ag-theme-balham
- 紧凑型浅色主题
ag-theme-balham-dark
- 暗色Balham主题
ag-theme-material
- Material设计主题
ag-theme-bootstrap
- Bootstrap风格主题
自定义行样式
<AgGridReact
getRowClass={(params) => {
if (params.data.status === 'Critical') {
return 'critical-row';
}
return '';
}}
getRowStyle={(params) => {
if (params.data.value < 0) {
return { background: '#ffcccc' };
}
return null;
}}
/>
自定义单元格样式
const columnDefs = [
{
field: 'price',
cellClass: 'price-cell',
cellStyle: params => {
if (params.value < 0) {
return { color: 'red', fontWeight: 'bold' };
}
return null;
},
cellClassRules: {
'cell-negative': params => params.value < 0,
'cell-positive': params => params.value >= 0
}
}
];
事件系统
主要网格事件
<AgGridReact
onGridReady={params => {
setGridApi(params.api);
setColumnApi(params.columnApi);
}}
onSelectionChanged={event => {
const selectedRows = event.api.getSelectedRows();
console.log('选中行:', selectedRows);
}}
onCellClicked={event => {
console.log('单元格点击:', event);
}}
onCellDoubleClicked={event => {
console.log('单元格双击:', event);
}}
onRowClicked={event => {
console.log('行点击:', event);
}}
onRowDoubleClicked={event => {
console.log('行双击:', event);
}}
onCellValueChanged={event => {
console.log('单元格值变化:', event);
}}
onSortChanged={event => {
console.log('排序变化:', event);
}}
onFilterChanged={event => {
console.log('过滤变化:', event);
}}
onColumnResized={event => {
console.log('列调整大小:', event);
}}
onColumnMoved={event => {
console.log('列移动:', event);
}}
onColumnVisible={event => {
console.log('列可见性变化:', event);
}}
onColumnPinned={event => {
console.log('列固定状态变化:', event);
}}
/>
API参考
Grid API
const [gridApi, setGridApi] = useState(null);
const [columnApi, setColumnApi] = useState(null);
const onGridReady = (params) => {
setGridApi(params.api);
setColumnApi(params.columnApi);
};
主要Grid API方法
方法 | 描述 |
---|
setRowData(rowData) | 设置行数据 |
applyTransaction(transaction) | 应用事务(新增、更新、删除行) |
refreshCells(params) | 刷新单元格 |
redrawRows(params) | 重绘行 |
paginationGoToPage(pageNumber) | 跳转到指定页 |
paginationGoToNextPage() | 下一页 |
paginationGoToPreviousPage() | 上一页 |
paginationGetCurrentPage() | 获取当前页码 |
paginationGetTotalPages() | 获取总页数 |
getDisplayedRowCount() | 获取显示的行数 |
getSelectedRows() | 获取选中行数据 |
getSelectedNodes() | 获取选中行节点 |
selectAll() | 全选 |
deselectAll() | 取消全选 |
selectAllFiltered() | 选择所有过滤后的行 |
getFilterModel() | 获取过滤模型 |
setFilterModel(model) | 设置过滤模型 |
destroyFilter(colKey) | 销毁过滤器 |
getSortModel() | 获取排序模型 |
setSortModel(model) | 设置排序模型 |
exportDataAsCsv(params) | 导出为CSV |
exportDataAsExcel(params) | 导出为Excel |
getRowNode(id) | 通过ID获取行节点 |
forEachNode(callback) | 遍历所有节点 |
forEachNodeAfterFilter(callback) | 遍历过滤后的节点 |
forEachNodeAfterFilterAndSort(callback) | 遍历过滤和排序后的节点 |
expandAll() | 展开所有行组 |
collapseAll() | 折叠所有行组 |
setDomLayout(layout) | 设置DOM布局 |
sizeColumnsToFit() | 调整列大小以适应网格宽度 |
autoSizeAllColumns() | 自动调整所有列大小 |
autoSizeColumns(colKeys) | 自动调整指定列大小 |
showLoadingOverlay() | 显示加载覆盖层 |
showNoRowsOverlay() | 显示无行覆盖层 |
hideOverlay() | 隐藏覆盖层 |
setRowHeight(params) | 设置行高 |
resetRowHeights() | 重置行高 |
ensureIndexVisible(index) | 确保索引可见 |
ensureNodeVisible(node) | 确保节点可见 |
ensureColumnVisible(key) | 确保列可见 |
flashCells(params) | 闪烁单元格 |
stopEditing() | 停止编辑 |
startEditingCell(params) | 开始编辑单元格 |
addRenderedRowListener(event, rowIndex, callback) | 添加渲染行监听器 |
purgeServerSideCache(route) | 清除服务器端缓存 |
destroy() | 销毁网格并清理资源 |
Column API
主要Column API方法
方法 | 描述 |
---|
setColumnDefs(colDefs) | 设置列定义 |
getColumn(key) | 获取列 |
getAllColumns() | 获取所有列 |
getAllDisplayedVirtualColumns() | 获取所有显示的虚拟列 |
getAllGridColumns() | 获取所有网格列 |
getDisplayedColAfter(col) | 获取指定列后的显示列 |
getDisplayedColBefore(col) | 获取指定列前的显示列 |
moveColumn(key, toIndex) | 移动列 |
moveColumns(keys, toIndex) | 移动多个列 |
autoSizeColumn(key) | 自动调整列大小 |
autoSizeColumns(keys) | 自动调整多个列大小 |
sizeColumnsToFit(width) | 调整列大小以适应宽度 |
setColumnVisible(key, visible) | 设置列可见性 |
setColumnsVisible(keys, visible) | 设置多个列可见性 |
setColumnPinned(key, pinned) | 设置列固定状态 |
setColumnsPinned(keys, pinned) | 设置多个列固定状态 |
resetColumnState() | 重置列状态 |
getColumnState() | 获取列状态 |
setColumnState(state) | 设置列状态 |
applyColumnState(params) | 应用列状态 |
isPivotMode() | 是否为透视模式 |
setPivotMode(pivotMode) | 设置透视模式 |
getSecondaryPivotColumn(pivotKeys, valueColKey) | 获取次要透视列 |
isPivotActive() | 透视是否启用 |
getRowGroupColumns() | 获取行分组列 |
setRowGroupColumns(colKeys) | 设置行分组列 |
addRowGroupColumn(colKey) | 添加行分组列 |
removeRowGroupColumn(colKey) | 移除行分组列 |
moveRowGroupColumn(fromIndex, toIndex) | 移动行分组列 |
getPivotColumns() | 获取透视列 |
setPivotColumns(colKeys) | 设置透视列 |
addPivotColumn(colKey) | 添加透视列 |
removePivotColumn(colKey) | 移除透视列 |
movePivotColumn(fromIndex, toIndex) | 移动透视列 |
getValueColumns() | 获取值列 |
setValueColumns(colKeys) | 设置值列 |
addValueColumn(colKey) | 添加值列 |
removeValueColumn(colKey) | 移除值列 |
moveValueColumn(fromIndex, toIndex) | 移动值列 |
高级配置实例
完整网格配置示例
import React, { useState, useEffect, useRef } from 'react'
import { AgGridReact } from 'ag-grid-react'
import 'ag-grid-community/styles/ag-grid.css'
import 'ag-grid-community/styles/ag-theme-alpine.css'
import 'ag-grid-enterprise'
// 自定义单元格渲染器
const CustomCellRenderer = (props) => {
return <span style={{ color: props.value < 0 ? 'red' : 'green' }}>{props.value}</span>
}
function AdvancedGrid() {
const gridRef = useRef()
const [rowData, setRowData] = useState([])
const [gridApi, setGridApi] = useState(null)
const [columnApi, setColumnApi] = useState(null)
// 列定义
const columnDefs = [
{
headerName: '运动员',
field: 'athlete',
minWidth: 170,
checkboxSelection: true,
headerCheckboxSelection: true,
filter: 'agTextColumnFilter',
floatingFilter: true
},
{
headerName: '年龄',
field: 'age',
filter: 'agNumberColumnFilter',
editable: true,
cellRenderer: CustomCellRenderer
},
{
headerName: '国家',
field: 'country',
filter: 'agSetColumnFilter',
rowGroup: true
},
{
headerName: '年份',
field: 'year',
filter: 'agSetColumnFilter'
},
{
headerName: '日期',
field: 'date',
filter: 'agDateColumnFilter',
cellRenderer: (params) => {
return new Date(params.value).toLocaleDateString()
}
},
{
headerName: '金牌',
field: 'gold',
filter: 'agNumberColumnFilter',
aggFunc: 'sum'
},
{
headerName: '银牌',
field: 'silver',
filter: 'agNumberColumnFilter',
aggFunc: 'sum'
}
]
// 默认列定义
const defaultColDef = {
flex: 1,
minWidth: 100,
sortable: true,
filter: true,
resizable: true,
floatingFilter: true
}
// 网格准备完成
const onGridReady = (params) => {
setGridApi(params.api)
setColumnApi(params.columnApi)
fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
.then(resp => resp.json())
.then(data => {
setRowData(data)
})
}
// 导出为CSV
const onExportClick = () => {
gridApi.exportDataAsCsv({
fileName: 'olympic-winners.csv',
columnKeys: ['athlete', 'age', 'country', 'year', 'gold', 'silver']
})
}
// 自动调整列大小
const onFitColsClick = () => {
gridApi.sizeColumnsToFit()
}
useEffect(() => {
if (gridApi) {
// 初始化操作
gridApi.sizeColumnsToFit()
}
}, [gridApi])
return (
<div className="ag-theme-alpine" style={{ height: 600, width: '100%' }}>
<div className="controls" style={{ marginBottom: '10px' }}>
<button onClick={onExportClick}>导出CSV</button>
<button onClick={onFitColsClick}>适应列宽</button>
</div>
<AgGridReact
ref={gridRef}
rowData={rowData}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
enableRangeSelection={true}
rowSelection="multiple"
rowGroupPanelShow="always"
pivotPanelShow="always"
pagination={true}
paginationPageSize={10}
animateRows={true}
onGridReady={onGridReanimateRows={true}
onGridReady={onGridReady}
suppressAggFuncInHeader={true}
getRowStyle={(params) => { if (params.node.rowIndex % 2 === 0) { return { background: '#f5f5f5' }
企业版高级功能
行分组与聚合
行分组允许根据一个或多个列对数据进行分组,并对这些分组应用聚合函数(如求和、平均值等)。
<AgGridReact
rowGroupPanelShow="always" // 显示行分组面板('always', 'onlyWhenGrouping', 'never')
suppressAggFuncInHeader={false} // 在标题中显示聚合函数
groupDisplayType="singleColumn" // 分组显示类型('singleColumn', 'multipleColumns', 'groupRows', 'custom')
groupDefaultExpanded={1} // 默认展开的级别(-1表示全部展开)
showOpenedGroup={true} // 显示已打开的组
rowGroup={true} // 启用行分组
groupIncludeFooter={true} // 包含分组页脚
groupIncludeTotalFooter={true} // 包含总计页脚
groupSelectsChildren={true} // 选择组时自动选择子项
groupRemoveSingleChildren={false}// 移除单个子项组
groupHideOpenParents={true} // 隐藏打开的父组
autoGroupColumnDef={{ // 自动分组列定义
headerName: '分组',
minWidth: 250,
cellRendererParams: {
suppressCount: false, // 不隐藏计数
checkbox: true, // 显示复选框
suppressDoubleClickExpand: false, // 允许双击展开
suppressEnterExpand: false // 允许回车展开
}
}}
/>
聚合函数
const columnDefs = [
{
field: 'salesAmount',
aggFunc: 'sum', // 内置聚合函数:'sum', 'min', 'max', 'count', 'avg', 'first', 'last'
allowedAggFuncs: ['sum', 'avg', 'count', 'min', 'max'], // 允许的聚合函数
},
{
field: 'profitMargin',
// 自定义聚合函数
aggFunc: (params) => {
let sum = 0
let count = 0
params.values.forEach(value => {
if (value && value > 0) {
sum += value
count++
}
})
return count > 0 ? sum / count : null
}
}
]
筛选工具栏
<AgGridReact
enableAdvancedFilter={true}
advancedFilterParent="myContainer"
advancedFilterBuilderParams={{
readOnly: false,
maxDepth: 3
}}
/>
列工具面板
<AgGridReact
sideBar={{
toolPanels: [
{
id: 'columns',
labelDefault: '列',
labelKey: 'columns',
iconKey: 'columns',
toolPanel: 'agColumnsToolPanel',
toolPanelParams: {
suppressRowGroups: false,
suppressValues: false,
suppressPivots: false,
suppressPivotMode: false,
suppressColumnFilter: false,
suppressColumnSelectAll: false,
suppressColumnExpandAll: false
}
},
{
id: 'filters',
labelDefault: '筛选器',
labelKey: 'filters',
iconKey: 'filter',
toolPanel: 'agFiltersToolPanel',
toolPanelParams: {
suppressExpandAll: false,
suppressFilterSearch: false
}
}
],
defaultToolPanel: 'columns',
position: 'right' // 'left', 'right'
}}
/>
状态保存与恢复
// 保存状态
const saveState = () => {
const columnState = columnApi.getColumnState()
const filterState = gridApi.getFilterModel()
const sortState = gridApi.getSortModel()
const state = {
columns: columnState,
filters: filterState,
sort: sortState
}
localStorage.setItem('gridState', JSON.stringify(state))
}
// 恢复状态
const restoreState = () => {
const savedState = JSON.parse(localStorage.getItem('gridState'))
if (savedState) {
columnApi.applyColumnState({
state: savedState.columns,
applyOrder: true
})
gridApi.setSortModel(savedState.sort)
gridApi.setFilterModel(savedState.filters)
}
}
导出功能
const onExportCsv = () => {
gridApi.exportDataAsCsv({
fileName: 'my-export.csv',
skipHeader: false,
skipFooters: false,
skipGroups: false,
skipPinnedTop: false,
skipPinnedBottom: false,
allColumns: false,
onlySelected: false,
columnKeys: ['col1', 'col2', 'col3'],
suppressQuotes: false,
processCellCallback: (params) => {
return params.value;
},
processHeaderCallback: (params) => {
return params.column.getColDef().headerName;
}
});
};
const onExportExcel = () => {
gridApi.exportDataAsExcel({
fileName: 'my-export.xlsx',
sheetName: 'AG Grid Export',
headerRowHeight: 30,
rowHeight: 25,
addImageToCell: (rowIndex, col, value) => {
return {
image: {
id: 'logo',
base64: 'base64EncodedImage...',
imageType: 'png',
width: 100,
height: 50
}
};
}
});
};
键盘导航
<AgGridReact
tabToNextCell={(params) => {
// 自定义Tab键导航逻辑
const suggestedNextCell = params.nextCellPosition
// 如果是最后一行最后一列,返回第一行第一列
if (suggestedNextCell.rowIndex === params.maxRowIndex &&
suggestedNextCell.column.colId === params.maxColId) {
return {
rowIndex: 0,
column: params.columnApi.getAllDisplayedColumns()[0]
}
}
return suggestedNextCell
}}
navigateToNextCell={(params) => {
// 自定义方向键导航逻辑
const suggestedNextCell = params.nextCellPosition
// 实现自定义逻辑
return suggestedNextCell
}}
enableCellTextSelection={true} // 允许选择单元格文本
ensureDomOrder={true} // 确保DOM顺序与视觉顺序一致(对于辅助功能)
suppressKeyboardEvent={(params) => {
// 返回true表示抑制事件
return params.event.key === 'Enter' && params.editing
}}
/>
列头组
const columnDefs = [ { headerName: '运动员信息', children: [ { field: 'athlete', headerName: '姓名' }, { field: 'age', headerName: '年龄' }, { field: 'country', headerName: '国家' } ]
},
{
headerName: '成绩统计',
children: [
{ field: 'gold', headerName: '金牌' },
{ field: 'silver', headerName: '银牌' },
{ field: 'bronze', headerName: '铜牌' },
{ field: 'total', headerName: '总计' }
]
}
];
单元格样式与条件格式
const columnDefs = [
{
field: 'value',
cellClassRules: {
'cell-red': params => params.value < 0,
'cell-amber': params => params.value >= 0 && params.value < (params.data.target * 0.5),
'cell-green': params => params.value >= (params.data.target * 0.5)
},
cellStyle: params => {
if (params.value < 0) {
return { backgroundColor: '#ffcccc' };
} else if (params.value < 50) {
return { backgroundColor: '#ffffcc' };
} else {
return { backgroundColor: '#ccffcc' };
}
}
}
];
右键菜单
<AgGridReact
getContextMenuItems={(params) => {
const result = [
{
name: '导出选中行',
action: () => {
params.api.exportDataAsCsv({ onlySelected: true })
},
icon: '<i class="fa fa-download"></i>'
},
{
name: '复制单元格',
shortcut: 'Ctrl+C',
action: () => {
const value = params.value || ''
navigator.clipboard.writeText(value)
}
},
'separator',
'copy',
'copyWithHeaders',
'paste',
'separator',
'export',
{
name: '自定义操作',
action: () => {
console.log('自定义操作', params)
},
disabled: !params.node, // 如果没有节点,则禁用
tooltip: '执行自定义操作'
}
]
return result
}}
allowContextMenuWithControlKey={true} // 允许使用Ctrl键调出上下文菜单
suppressContextMenu={false} // 不禁用上下文菜单
/>
图表集成
<AgGridReact
enableCharts={true}
popupParent={document.body}
chartThemes={['ag-pastel', 'ag-material']}
chartThemeOverrides={{
common: {
title: {
enabled: true,
fontSize: 20
},
legend: {
position: 'bottom',
spacing: 15
}
},
column: {
axes: {
category: {
label: {
rotation: 0
}
}
}
}
}}
onChartCreated={(event) => {
console.log('图表已创建:', event);
}}
onChartDestroyed={(event) => {
console.log('图表已销毁:', event);
}}
onChartRangeSelectionChanged={(event) => {
console.log('图表范围选择已更改:', event);
}}
/>
工具提示(Tooltips)
const columnDefs = [
{
field: 'athlete',
tooltipField: 'athlete',
tooltipComponent: 'customTooltip',
tooltipComponentParams: {
color: '#ececec'
}
}
];
const CustomTooltip = props => {
const data = props.data;
return (
<div className="custom-tooltip" style={{ backgroundColor: props.color }}>
<p><span>运动员: </span> {data.athlete}</p>
<p><span>国家: </span> {data.country}</p>
<p><span>年份: </span> {data.year}</p>
</div>
);
};
<AgGridReact
frameworkComponents={{
customTooltip: CustomTooltip
}}
tooltipShowDelay={200} // 工具提示显示延迟(毫秒)
tooltipHideDelay={1000} // 工具提示隐藏延迟(毫秒)
/>
行拖拽与拖放
<AgGridReact
rowDragManaged={true}
animateRows={true}
suppressMoveWhenRowDragging={false}
suppressRowDrag={false}
onRowDragEnd={(event) => {
console.log('行从索引 ' + event.overIndex + ' 移动到索引 ' + event.overIndex);
}}
/>
const columnDefs = [
{
rowDrag: true,
maxWidth: 50,
suppressMenu: true,
rowDragText: (params, dragItemCount) => {
return dragItemCount > 1
? dragItemCount + ' 项'
: params.rowNode.data.athlete;
}
},
];
全屏切换
const [isFullScreen, setIsFullScreen] = useState(false);
const toggleFullScreen = () => {
const eGridDiv = document.querySelector('#myGrid');
if (!isFullScreen) {
if (eGridDiv.requestFullscreen) {
eGridDiv.requestFullscreen();
} else if (eGridDiv.msRequestFullscreen) {
eGridDiv.msRequestFullscreen();
} else if (eGridDiv.webkitRequestFullscreen) {
eGridDiv.webkitRequestFullscreen();
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
setIsFullScreen(!isFullScreen);
};
return (
<>
<button onClick={toggleFullScreen}>
{isFullScreen ? '退出全屏' : '全屏显示'}
</button>
<div id="myGrid" className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact ... />
</div>
</>
);
行分页器自定义
<AgGridReact
pagination={true}
paginationPageSize={10}
paginationNumberFormatter={(params) => {
return '第 ' + params.value + ' 页'
}}
paginationAutoPageSize={false} // 禁用自动页面大小
suppressPaginationPanel={true} // 禁用默认分页面板
/>
// 自定义分页控件
const CustomPagination = () => {
const [gridApi, setGridApi] = useState(null)
const onPageSizeChanged = (event) => {
const value = event.target.value
gridApi.paginationSetPageSize(Number(value))
}
const onBtFirst = () => {
gridApi.paginationGoToFirstPage()
}
const onBtPrevious = () => {
gridApi.paginationGoToPreviousPage()
}
const onBtNext = () => {
gridApi.paginationGoToNextPage()
}
const onBtLast = () => {
gridApi.paginationGoToLastPage()
}
return (
<div className="pagination-controls">
<button onClick={onBtFirst}>首页</button>
<button onClick={onBtPrevious}>上一页</button>
<span>页 {gridApi ? gridApi.paginationGetCurrentPage() + 1 : 0} / {gridApi ? gridApi.paginationGetTotalPages() : 0}</span>
<button onClick={onBtNext}>下一页</button>
<button onClick={onBtLast}>末页</button>
<span>每页显示:</span>
<select onChange={onPageSizeChanged}>
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
)
}
无限滚动(服务器端)
<AgGridReact
rowModelType="infinite"
cacheBlockSize={100} // 缓存块大小
maxBlocksInCache={10} // 缓存中的最大块数
infiniteInitialRowCount={1000} // 初始行数
maxConcurrentDataRequests={2} // 最大并发数据请求数
datasource={{ // 数据源
getRows: (params) => {
console.log('请求数据行: ', params.startRow, ' 到 ', params.endRow)
// 获取排序和筛选模型
const sortModel = params.sortModel
const filterModel = params.filterModel
// 服务器请求
fetch(
api/data?start=${params.startRow}&end=${params.endRow}
)
.then(response => response.json())
.then(response => {
// 提供行数据和最后一行索引
params.successCallback(response.rows, response.lastRow)
})
.catch(error => {
// 处理错误
params.failCallback()
})
}
}}
/>
服务器端行模型(企业版)
<AgGridReact
rowModelType="serverSide"
serverSideInfiniteScroll={true}
cacheBlockSize={100}
maxBlocksInCache={10}
purgeClosedRowNodes={true} // 清除关闭的行节点
blockLoadDebounceMillis={100} // 块加载防抖毫秒
serverSideDatasource={{ // 服务器端数据源
getRows: (params) => {
// 构建请求
const request = {
startRow: params.request.startRow,
endRow: params.request.endRow,
rowGroupCols: params.request.rowGroupCols,
valueCols: params.request.valueCols,
pivotCols: params.request.pivotCols,
pivotMode: params.request.pivotMode,
groupKeys: params.request.groupKeys,
filterModel: params.request.filterModel,
sortModel: params.request.sortModel
}
// 发送请求
fetch('api/data', {
method: 'post',
body: JSON.stringify(request)
})
.then(response => response.json())
.then(response => {
// 处理结果
if (response.success) {
// 计算最后一行
const lastRow = response.lastRow
// 提供行数据
params.success({ rowData: response.rows, rowCount: lastRow })
} else {
params.fail()
}
})
.catch(error => {
params.fail()
})
}
}}
getServerSideGroupKey={(dataItem) => {
// 自定义组键生成
return dataItem.id.toString()
}}
isServerSideGroupOpenByDefault={(params) => {
// 自动展开特定组
return params.key === 'GroupA'
}}
isServerSideGroup={(dataItem) => {
// 确定数据项是否为组
return dataItem.hasOwnProperty('group') && dataItem.group
}}
getChildCount={(dataItem) => {
// 获取子项计数
return dataItem.childCount
}}
/>
树形数据高级配置
<AgGridReact
treeData={true} // 启用树形数据
getDataPath={(data) => { // 获取数据路径函数
return data.filePath
}}
autoGroupColumnDef={{ // 自动分组列定义
headerName: '文件',
field: 'fileName',
cellRendererParams: {
checkbox: true, // 显示复选框
suppressCount: false, // 不隐藏计数
innerRenderer: 'fileCellRenderer' // 内部渲染器
}
}}
groupDefaultExpanded={1} // 默认展开级别
enableGroupEdit={true} // 启用组编辑
groupSelectsChildren={true} // 组选择子项
groupIncludeFooter={true} // 包含组页脚
showOpenedGroup={true} // 显示已打开的组
groupHideOpenParents={true} // 隐藏打开的父项
groupRemoveSingleChildren={false} // 保留单个子项
groupMultiAutoColumn={false} // 禁用多自动列
excludeChildrenWhenTreeDataFiltering={false} // 树数据过滤时不排除子项
/>
批量操作与事务处理
gridApi.applyTransaction({
add: newRows, // 添加新行
update: updatedRows, // 更新现有行
remove: removedRows // 删除行
});
const applyTransactionResult = gridApi.applyTransaction({
add: [{ id: 1, name: '新项目' }],
update: [{ id: 2, name: '更新项目' }],
remove: [{ id: 3 }]
});
console.log('添加的行节点:', applyTransactionResult.add);
console.log('更新的行节点:', applyTransactionResult.update);
console.log('删除的行节点:', applyTransactionResult.remove);
gridApi.applyTransactionAsync({
add: rowsToAdd,
update: rowsToUpdate,
remove: rowsToRemove
}, (res) => {
console.log('异步操作完成:', res);
});
行高设置与自动行高
<AgGridReact
rowHeight={50}
getRowHeight={(params) => {
if (params.node.group) {
return 50;
} else {
return 25;
}
}}
enableCellTextSelection={true}
suppressRowTransform={false}
/>
const autoHeightColumn = {
field: 'description',
width: 200,
cellClass: 'cell-wrap-text',
autoHeight: true,
cellStyle: { 'white-space': 'normal' }
};
主从表视图
<AgGridReact
masterDetail={true} // 启用主从视图
detailCellRenderer="MyDetailComponent" // 详情单元格渲染器
detailRowHeight={400} // 详情行高度
detailRowAutoHeight={true} // 自动调整详情行高度
isRowMaster={(params) => { // 确定行是否为主行
return true
}}
onFirstDataRendered={(params) => { // 首次数据渲染后
// 展开第一行
setTimeout(() => {
params.api.getDisplayedRowAtIndex(0).setExpanded(true)
}, 0)
}}
/>
// 详情组件示例
const DetailCellRenderer = (props) => {
const { data } = props
// 内部表格列定义
const detailColumnDefs = [
{ field: 'callId' },
{ field: 'direction' },
{ field: 'duration', valueFormatter: params =>
${params.value} 秒
},
{ field: 'switchCode' }
]
return (
<div className="detail-grid-wrapper">
<AgGridReact
columnDefs={detailColumnDefs}
rowData={data.callRecords}
defaultColDef={{
flex: 1,
sortable: true
}}
/>
</div>
)
}
单元格编辑器与渲染器
自定义编辑器
// 自定义数字编辑器
const NumericCellEditor = React.forwardRef((props, ref) => {
const [value, setValue] = useState(props.value)
const refInput = useRef(null)
useEffect(() => {
// 聚焦的单元格
setTimeout(() => refInput.current.focus())
}, [])
const getValue = () => {
return value
}
const isCancelAfterEnd = () => {
return document.activeElement && document.activeElement !== refInput.current
}
const onInputChange = event => {
setValue(event.target.value)
}
useImperativeHandle(ref, () => {
return {
getValue,
isCancelAfterEnd
}
})
return (
<input
ref={refInput}
type="number"
value={value}
onChange={onInputChange}
style={{ width: '100%' }}
/>
)
})
// 在列定义中使用
const columnDefs = [
{
field: 'age',
cellEditor: 'numericCellEditor',
cellEditorParams: {
min: 0,
max: 100
}
}
]
// 注册组件
<AgGridReact
frameworkComponents={{
numericCellEditor: NumericCellEditor
}}
/>
自定义渲染器
// 自定义按钮渲染器
const ButtonCellRenderer = props => {
const buttonClicked = () => {
alert(
${props.data.name} 被点击了!
)
}
return (
<button onClick={buttonClicked} className="action-button">
点击
</button>
)
}
// 在列定义中使用
const columnDefs = [
{
headerName: '操作',
field: 'id',
cellRenderer: 'buttonCellRenderer',
cellRendererParams: {
clicked: function(field) {
alert(
${field} was clicked
)
}
}
}
]
// 注册组件
<AgGridReact
frameworkComponents={{
buttonCellRenderer: ButtonCellRenderer
}}
/>
性能优化
大数据集处理
<AgGridReact
// 使用虚拟化提高性能
suppressRowVirtualisation={false} // 启用行虚拟化
suppressColumnVirtualisation={false} // 启用列虚拟化
rowBuffer={10} // 缓冲的行数
// 惰性加载数据 - 无限滚动
rowModelType="infinite"
cacheBlockSize={100}
maxBlocksInCache={10}
infiniteInitialRowCount={1000}
// 使用不可变数据模式
immutableData={true}
getRowNodeId={(data) => data.id} // 唯一ID函数
// 优化更新
enableCellChangeFlash={true} // 启用单元格更改闪烁
suppressPropertyNamesCheck={true}// 禁用属性名称检查
suppressChangeDetection={false} // 禁用变更检测
// 调试性能
debug={false} // 禁用调试模式
suppressAnimationFrame={false} // 使用动画帧
/>
使用企业版的服务器端行模型
<AgGridReact
rowModelType="serverSide"
purgeClosedRowNodes={true}
maxBlocksInCache={10}
cacheBlockSize={100}
blockLoadDebounceMillis={200} // 定义加载
blockLoadDebounceMillis={200} // 定义数据加载的防抖时间,减少服务器请求
// 优化分组数据处理
suppressModelUpdateAfterUpdateTransaction={true} // 事务更新后禁止模型更新
// 减轻DOM负载
suppressColumnVirtualisation={false} // 保持列虚拟化启用
suppressRowVirtualisation={false} // 保持行虚拟化启用
// 避免不必要的重新渲染
getRowNodeId={(data) => data.id} // 唯一ID函数
enableCellChangeFlash={true} // 仅闪烁变更的单元格
/>
常见使用场景与解决方案
条件格式化(根据数据值设置样式)
const columnDefs = [
{
field: 'price',
cellClassRules: {
'cell-negative': params => params.value < 0,
'cell-warning': params => params.value >= 0 && params.value < 30000,
'cell-positive': params => params.value >= 30000
},
cellStyle: params => {
if (params.value < 0) {
return { backgroundColor: '#ffaaaa', fontWeight: 'bold' };
} else if (params.value < 30000) {
return { backgroundColor: '#ffffaa' };
} else {
return { backgroundColor: '#aaffaa', fontWeight: 'bold' };
}
}
}
];
单元格编辑验证
const columnDefs = [
{
field: 'age',
editable: true,
cellEditorParams: {
maxLength: 2
},
cellEditor: (params) => {
return params.value;
},
valueSetter: (params) => {
const newValue = Number(params.newValue);
if (isNaN(newValue) || newValue < 0 || newValue > 100) {
return false;
}
params.data.age = newValue;
return true;
}
}
];
<AgGridReact
onCellValueChanged={(params) => {
if (params.column.colId === 'age') {
const isValid = params.data.age >= 0 && params.data.age <= 100;
if (!isValid) {
alert('年龄必须在0到100之间');
params.node.setDataValue('age', params.oldValue);
}
}
}}
/>
单元格合并(跨越单元格)
<AgGridReact
suppressRowTransform={true} // 禁用行转换以支持覆盖单元格
columnDefs={[
{
field: 'name',
cellClassRules: {
'cell-span': params => params.data && params.data.span
},
cellStyle: params => {
if (params.data && params.data.span) {
return { zIndex: 1 }
}
}
},
{ field: 'account' }
]}
// 自定义合并单元格处理
processCellForClipboard={(params) => {
return params.value
}}
/>
// 相关CSS
/*
.cell-span {
position: absolute
top: 0
left: 0
height: 100px
width: 200px
z-index: 1
}
*/
自定义筛选器
// 自定义筛选器组件
const CustomFilter = props => {
const [filterText, setFilterText] = useState('')
// 当筛选器值改变时
const onFilterChange = event => {
const newValue = event.target.value
setFilterText(newValue)
props.filterChangedCallback()
}
// 实现筛选函数
const doesFilterPass = (params) => {
const fieldValue = params.data[props.colDef.field]
return fieldValue && fieldValue.toString().toLowerCase().indexOf(filterText.toLowerCase()) >= 0
}
// 提供接口供AG Grid调用
const isFilterActive = () => {
return filterText != null && filterText !== ''
}
// 获取筛选器的模型
const getModel = () => {
return { value: filterText }
}
// 设置筛选器的模型
const setModel = (model) => {
if (model) {
setFilterText(model.value)
} else {
setFilterText('')
}
}
return (
<div className="custom-filter">
<input
type="text"
value={filterText}
onChange={onFilterChange}
placeholder="输入筛选..."
/>
</div>
)
}
// 注册并使用自定义筛选器
const columnDefs = [
{
field: 'name',
filter: 'customFilter'
}
]
<AgGridReact
frameworkComponents={{
customFilter: CustomFilter
}}
/>
导出为CSV和Excel
const onExportCSV = () => {
gridApi.exportDataAsCsv({
fileName: '导出数据.csv',
columnKeys: ['name', 'age', 'country'], // 指定要导出的列
skipHeader: false, // 包含表头
suppressQuotes: false, // 保留引号
skipGroups: true, // 跳过组行
skipFooters: true, // 跳过页脚
columnSeparator: ',', // 列分隔符
processCellCallback: (params) => {
if (params.column.colId === 'age') {
return params.value + '岁';
}
return params.value;
},
processHeaderCallback: (params) => {
const colId = params.column.colId;
if (colId === 'name') return '姓名';
if (colId === 'age') return '年龄';
if (colId === 'country') return '国家';
return params.column.getColDef().headerName;
}
});
};
const onExportExcel = () => {
gridApi.exportDataAsExcel({
fileName: '导出数据.xlsx',
sheetName: '数据表',
columnKeys: ['name', 'age', 'country'],
exportMode: 'xlsx', // 'xlsx' 或 'xml'
headerRowHeight: 30, // 表头行高
rowHeight: 25, // 内容行高
suppressTextAsCDATA: true, // 抑制文本作为CDATA
customHeader: [ // 自定义表头
[{
styleId: 'headAppend',
data: {
type: 'String',
value: '导出数据报表'
},
mergeAcross: 5
}]
],
customFooter: [ // 自定义页脚
[{
styleId: 'footAppend',
data: {
type: 'String',
value: '©2025 公司名称'
},
mergeAcross: 5
}]
],
processRowGroupCallback: (params) => {
return params.node.key;
},
addImageToCell: (rowIndex, col, value) => {
if (col.colId === 'image') {
return {
image: {
id: 'logo',
base64: 'base64EncodedImage...',
imageType: 'png',
width: 50,
height: 25
}
};
}
return null;
}
});
};
<button onClick={onExportCSV}>导出CSV</button>
<button onClick={onExportExcel}>导出Excel</button>
快速过滤(全局搜索)
const [quickFilterText, setQuickFilterText] = useState('')
const onFilterTextChange = (event) => {
setQuickFilterText(event.target.value)
}
return (
<div>
<div className="quick-filter-container">
<input
type="text"
onChange={onFilterTextChange}
placeholder="搜索..."
value={quickFilterText}
/>
</div>
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
quickFilterText={quickFilterText} // 设置快速过滤文本
cacheQuickFilter={true} // 缓存快速过滤结果
enableCellTextSelection={true} // 允许选择单元格文本
/>
</div>
</div>
)
动态改变列定义
// 初始列定义
const [columnDefs, setColumnDefs] = useState([
{
field: 'name',
headerName: '姓名'
},
{
field: 'age',
headerName: '年龄'
},
{
field: 'country',
headerName: '国家'
}
])
// 添加新列
const addColumn = () => {
const newColumn = {
field: 'score',
headerName: '分数'
}
setColumnDefs([...columnDefs, newColumn])
}
// 删除列
const removeColumn = (field) => {
const updatedCols = columnDefs.filter(col => col.field !== field)
setColumnDefs(updatedCols)
}
// 修改列属性
const updateColumn = (field, property, value) => {
const updatedCols = columnDefs.map(col => {
if (col.field === field) {
return { ...col, [property]: value }
}
return col
})
setColumnDefs(updatedCols)
}
// 使用Column API动态更新列
useEffect(() => {
if (columnApi) {
columnApi.setColumnDefs(columnDefs)
}
}, [columnDefs, columnApi])
保存和恢复用户首选项
// 保存网格状态
const saveGridState = () => {
// 获取列状态
const columnState = columnApi.getColumnState()
// 获取过滤器模型
const filterModel = gridApi.getFilterModel()
// 获取排序模型
const sortModel = gridApi.getSortModel()
// 组合状态
const gridState = {
columnState,
filterModel,
sortModel
}
// 保存到本地存储
localStorage.setItem('myGridState', JSON.stringify(gridState))
}
// 恢复网格状态
const restoreGridState = () => {
const savedState = localStorage.getItem('myGridState')
if (savedState) {
const gridState = JSON.parse(savedState)
// 应用列状态
if (gridState.columnState) {
columnApi.applyColumnState({
state: gridState.columnState,
applyOrder: true
})
}
// 应用过滤器模型
if (gridState.filterModel) {
gridApi.setFilterModel(gridState.filterModel)
}
// 应用排序模型
if (gridState.sortModel) {
gridApi.setSortModel(gridState.sortModel)
}
}
}
主题和样式定制
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
// 自定义SCSS (如果使用)
/*
@import '~ag-grid-community/src/styles/ag-grid.scss';
@import '~ag-grid-community/src/styles/ag-theme-alpine/sass/ag-theme-alpine-mixin.scss';
.ag-theme-custom {
@include ag-theme-alpine((
odd-row-background-color:
row-hover-color:
header-background-color:
header-foreground-color:
));
.ag-header-cell {
font-weight: bold;
}
.ag-row-odd {
background-color:
}
.ag-row-hover {
background-color:
}
}
*/
// 使用内联样式
const gridStyle = {
'--ag-header-height': '50px',
'--ag-header-foreground-color': 'white',
'--ag-header-background-color': '#1890ff',
'--ag-header-cell-hover-background-color': '#0c7cd5',
'--ag-header-cell-moving-background-color': '#0c7cd5',
'--ag-row-border-color': '#dde2eb',
'--ag-row-hover-color': '#f0f8ff',
'--ag-odd-row-background-color': '#f8f8f8',
'--ag-cell-horizontal-border': '1px solid #dde2eb',
'--ag-selected-row-background-color': '#b7e4ff',
'--ag-range-selection-border-color': '#2196f3',
'--ag-font-size': '14px',
'--ag-font-family': 'Arial, Helvetica, sans-serif'
};
// 应用样式
<div className="ag-theme-alpine" style={{ ...gridStyle, height: 500, width: '100%' }}>
<AgGridReact
// 网格配置...
/>
</div>
单元格键盘导航
<AgGridReact
tabToNextCell={(params) => {
return params.nextCellPosition;
}}
navigateToNextCell={(params) => {
const key = params.event.key;
const nextCell = params.nextCellPosition;
if (key === 'ArrowRight' || key === 'ArrowLeft') {
}
return nextCell;
}}
suppressKeyboardEvent={(params) => {
const event = params.event;
const key = event.key;
if (params.editing && key === 'Enter') {
return true;
}
return false;
}}
processKeyboardEvent={(params) => {
const event = params.event;
if (event.key === 'Delete' && !params.editing) {
const focusedCell = params.api.getFocusedCell();
if (focusedCell) {
params.api.startEditingCell({
rowIndex: focusedCell.rowIndex,
colKey: focusedCell.column.getColId(),
keyPress: event.key
});
setTimeout(() => {
params.api.stopEditing(true);
}, 50);
return true;
}
}
return false;
}}
/>
可拖拽列重排序
<AgGridReact
// 允许拖拽重排序列
suppressMovableColumns={false} // 允许移动列
suppressDragLeaveHidesColumns={true} // 阻止拖出隐藏列
allowDragFromColumnsToolPanel={true} // 允许从列工具面板拖拽
suppressColumnMoveAnimation={false} // 启用列移动动画
// 列移动事件处理
onColumnMoved={(event) => {
console.log('列已移动:', event)
}}
onColumnPinned={(event) => {
console.log('列固定状态已更改:', event)
}}
/>
使用虚拟DOM组件
import React, { useMemo } from 'react';
const PerformantGrid = ({ data }) => {
const columnDefs = useMemo(() => {
return [
{
field: 'name',
filter: 'agTextColumnFilter'
},
{
field: 'age',
filter: 'agNumberColumnFilter'
},
{
field: 'country',
filter: 'agSetColumnFilter'
}
];
}, []);
const defaultColDef = useMemo(() => {
return {
flex: 1,
minWidth: 150,
sortable: true,
filter: true
};
}, []);
const gridOptions = useMemo(() => {
return {
};
}, []);
return (
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact
rowData={data}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
// 其他属性...
/>
</div>
);
};
高级贴士与技巧
优化大数据集性能
- 使用虚拟化:默认开启,确保不要禁用行/列虚拟化
<AgGridReact
suppressRowVirtualisation={false}
suppressColumnVirtualisation={false}
/>
- 使用不可变数据模式:
<AgGridReact
immutableData={true}
getRowNodeId={(data) => data.id}
/>
- 使用企业版的服务器端行模型:
<AgGridReact
rowModelType="serverSide"
cacheBlockSize={100}
maxBlocksInCache={10}
/>
- 批量更新数据:
gridApi.applyTransactionAsync({
update: updatedRows
}, () => {
console.log('批量更新完成');
});
- 使用异步事务:
gridApi.applyTransactionAsync({
add: rowsToAdd,
update: rowsToUpdate,
remove: rowsToRemove
});
常见问题解决方案
- 网格不自动调整大小:
window.addEventListener('resize', () => {
setTimeout(() => {
gridApi.sizeColumnsToFit();
});
});
- 单元格编辑值不更新:
{
field: 'status',
valueGetter: (params) => {
return params.data ? params.data.status : '';
},
valueSetter: (params) => {
params.data.status = params.newValue;
return true;
}
}
- 动态更改rowData不刷新网格:
setRowData([...newData]);
gridApi.setRowData(newData);
- 过滤器不应用于新数据:
// 在更新数据后重新应用过滤器
const filterModel = gridApi.getFilterModel()
gridApi.setRowData(newData)
gridApi.setFilterModel(filterModel)
- 自定义组件不更新: 确保正确实现了组件生命周期方法及内部状态更新。
最佳实践
- 网格初始化时:
const onGridReady = (params) => {
setGridApi(params.api);
setColumnApi(params.columnApi);
params.api.sizeColumnsToFit();
params.columnApi.autoSizeColumns(['name', 'description']);
};
- React依赖管理:
const cellClickedHandler = useCallback((params) => {
console.log('单元格被点击:', params);
}, []);
<AgGridReact
onCellClicked={cellClickedHandler}
/>
- 优化渲染性能:
// 缓存网格组件
const gridComponent = useMemo(() => {
return (
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
// 其他配置...
/>
)
}, [rowData, columnDefs])
- 处理大数据更新:
gridApi.setSuppressEvents(true);
gridApi.applyTransaction({update: updatedRows});
gridApi.setSuppressEvents(false);
gridApi.onFilterChanged();
待完善...