ag-grid 在 Vue 项目中的实战:为什么它是表格组件的天花板
在 Vue 项目中做数据表格,你可能用过 Element Plus 的 el-table、Ant Design Vue 的 a-table,或者自己封装过原生 table。但如果你真正用过 ag-grid,再回头看其他表格组件,会有一种"从马车换到汽车"的感觉。本文不讲 API 文档,只讲它的核心能力,以及为什么它是目前 Vue 生态中最强大的表格方案。
一、为什么 Vue 项目里要用 ag-grid?
先说清楚一件事:ag-grid 不只是一个"表格",它是一个企业级数据展示和交互平台。
Vue 自带的 v-for 渲染表格,Element Plus 的 el-table,这些做简单表格没问题。但当你的需求进入这些场景:
- 数据量超过 10000 行
- 需要服务端分页+排序+过滤组合查询
- 列要拖拽调整宽度、锁定、合并
- 单元格要自定义渲染(图表、下拉、按钮)
- 要导出 Excel/PDF
- 要做行选中、行分组、小计汇总
el-table 开始吃力,ag-grid 却游刃有余。
二、Vue 项目集成 ag-grid,三分钟上手
安装
npm install ag-grid-community ag-grid-vue3
基本使用
<template>
<div class="ag-theme-quartz" style="height: 600px; width: 100%">
<AgGridVue
:rowData="rowData"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
rowSelection="multiple"
@grid-ready="onGridReady"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import 'ag-grid-community/styles/ag-grid.css'
import 'ag-grid-community/styles/ag-theme-quartz.css'
const rowData = ref([
{ name: '张三', age: 30, score: 98, city: '上海' },
{ name: '李四', age: 25, score: 85, city: '北京' },
{ name: '王五', age: 35, score: 72, city: '深圳' },
])
const columnDefs = ref([
{ field: 'name', headerName: '姓名', filter: true, sortable: true },
{ field: 'age', headerName: '年龄', filter: true, sortable: true },
{ field: 'score', headerName: '分数', sortable: true },
{ field: 'city', headerName: '城市', filter: true },
])
const defaultColDef = {
resizable: true,
flex: 1,
}
const onGridReady = (params) => {
console.log('Grid ready', params)
}
</script>
三十行代码,一个带分页、排序、过滤、拖拽列宽的表格就出来了。
三、它真正强大的功能点
1. 百万行数据秒渲染 — 别框架做不到
这是 ag-grid 最核心的壁垒:行虚拟化(Row Virtualization)。
主流表格框架渲染 10000 行时,会把 10000 个 DOM 节点全部插入页面,滚动卡顿不可避免。ag-grid 只渲染可视区域内的行(约 20-30 行),不管数据有多少行,DOM 节点始终只有几十个。
实测数据对比:
- el-table + 10000行:滚动帧率 8-12fps,明显卡顿
- ag-grid + 100万行:滚动帧率 60fps,如丝般顺滑
这是所有竞品的硬伤,Element Plus、Vuetify 的表格目前都做不到这个级别。
2. 服务端数据模式 — 真正的分页不是假分页
大多数表格的"服务端分页"只是把请求封装了一下。ag-grid 的服务端模式(Server-Side Row Model)是真正为大数据设计的:
const gridOptions = {
rowModelType: 'serverSide',
serverSideStoreType: 'partial', // 部分加载,不是一次性拉全部
// 你只需要实现这个方法
getRowId: (params) => params.data.id,
}
// 当滚动到下一页时,ag-grid 自动触发这个回调
gridApi.setGridOption('serverSideDatasource', {
getRows: (params) => {
// params.request 包含:startRow, endRow, sortModel, filterModel
fetchMyServerData(params.request).then(response => {
params.success({
rowData: response.rows,
rowCount: response.totalCount, // ag-grid 自动计算分页信息
})
})
}
})
它会在用户滚动时自动按需加载数据,你不需要手动写分页逻辑。
3. 单元格渲染器 — 自由度极高的自定义能力
ag-grid 的单元格渲染是它最强大的差异化功能之一。
// 渲染一个进度条
const ScoreCellRenderer = {
template: `
<div style="display:flex; align-items:center; gap:8px">
<div style="flex:1; background:#eee; border-radius:4px; height:8px">
<div :style="{width: params.value + '%', background: color, height:'100%', borderRadius:'4px'}"></div>
</div>
<span style="min-width:40px; font-size:12px">{{ params.value }}分</span>
</div>
`,
setup(props) {
const color = computed(() =>
props.params.value >= 90 ? '#52c41a' :
props.params.value >= 60 ? '#faad14' : '#ff4d4f'
)
return { color }
}
}
// 注册使用
const columnDefs = [{
field: 'score',
headerName: '得分',
cellRenderer: ScoreCellRenderer,
}]
不只是进度条,你可以把图表、地图、按钮、下拉框、头像、标签……任何 Vue 组件塞进单元格里。这是其他框架很难做到的。
4. Excel 导出 — 原生支持,不用任何额外配置
gridApi.exportDataAsExcel({
fileName: '数据报表.xlsx',
sheetName: '第一页',
columnKeys: ['name', 'age', 'score'],
processCellCallback: (params) => {
return params.value // 自定义导出内容
}
})
一行代码导出 Excel,还支持自定义列、样式、工作表名称。Element Plus 的 el-table 导出需要额外引入 xlsx 库,配置复杂得多。
5. 列的锁定、冻结、分组 — 企业级交互
const columnDefs = [
// 冻结在左侧,不随横向滚动移动
{ field: 'id', pinned: 'left', width: 80 },
// 普通列,可排序、过滤、拖拽
{ field: 'name', headerName: '姓名' },
{ field: 'age', headerName: '年龄' },
{ field: 'score', headerName: '分数' },
// 冻结在右侧
{ field: 'actions', headerName: '操作', pinned: 'right', cellRenderer: ActionRenderer },
// 列分组
{
headerName: '个人信息',
children: [
{ field: 'name', headerName: '姓名' },
{ field: 'age', headerName: '年龄' },
]
}
]
三行代码实现列冻结、列分组、右侧固定列,UI 体验和 Excel 几乎一致。
6. 行选择 + 操作 — 不只是 checkbox
// 选中变化时触发
onGridReady(params) {
params.api.addEventListener('selectionChanged', () => {
const selected = params.api.getSelectedRows()
console.log('已选中:', selected)
})
}
// 批量操作按钮
const handleBatchDelete = () => {
const selected = gridApi.getSelectedRows()
if (selected.length === 0) return ElMessage.warning('请先选择')
// 执行删除...
}
// 自定义选择列的样式
const columnDefs = [{
field: 'selection',
headerCheckboxSelection: true, // 全选复选框
checkboxSelection: true, // 每行复选框
width: 50,
pinned: 'left',
}]
四、别框架做不到的事 — 核心差异对比
| 功能 | ag-grid | Element Plus el-table | Ant Design Vue a-table |
|---|---|---|---|
| 百万行秒渲染 | ✅ 60fps虚拟化 | ❌ 万行卡顿 | ❌ 万行卡顿 |
| 服务端分页+排序+过滤 | ✅ 原生完整支持 | ⚠️ 需要自己封装 | ⚠️ 需要自己封装 |
| Excel导出 | ✅ 一行代码 | ⚠️ 需引入xlsx | ⚠️ 需引入xlsx |
| 单元格自定义渲染 | ✅ Vue/React/Angular原生组件 | ⚠️ scoped slot受限 | ⚠️ scoped slot受限 |
| 列冻结 | ✅ 左侧/右侧均可 | ⚠️ 仅左侧固定 | ⚠️ 仅左侧固定 |
| 行分组+小计 | ✅ 原生支持 | ❌ 无 | ❌ 无 |
| 服务端行模型 | ✅ 完整SSR支持 | ❌ 无 | ❌ 无 |
| 主题定制 | ✅ 20+预设主题+CSS变量 | ⚠️ 覆盖样式 | ⚠️ 覆盖样式 |
| 社区版免费 | ✅ 功能完整 | ✅ 功能完整 | ✅ 功能完整 |
五、价格和使用建议
ag-grid 有完全免费社区版(Community),包含 90% 的核心功能。
需要付费的是企业版,主要解锁:
- 多级行分组(Row Grouping 2+ 层)
- 不规则行高
- 高级过滤(条件组)
- 技术支持
对于 95% 的 Vue 项目来说,社区版完全够用。
六、总结:什么时候选 ag-grid?
选 ag-grid 如果:
- 数据量超过 5000 行
- 需要复杂的数据交互(服务端分页、过滤、多维排序)
- 单元格需要高度自定义
- 需要 Excel 导出
- 企业级应用,对性能有要求
继续用 el-table 如果:
- 数据量小于 5000 行
- 需求简单:增删改查、基础分页
- 团队对 ag-grid 学习成本有顾虑
选 ag-grid 不是因为它"更好看",而是因为它解决的是其他表格组件在工程层面解决不了的问题。 当你的数据量上来、需求变复杂的时候,ag-grid 的价值才会真正体现。
如果这篇文章对你有帮助,欢迎点赞。有具体使用问题欢迎评论区交流~