Vue3中AG Grid自定义单元格渲染器引发行绘制冲突报错
场景重现步骤
- 创建自定义单元格渲染组件:
const ButtonAgGrid= { template: "<button>{{ displayValue }}</button>", setup(props) { const displayValue = 'TEST-TEXT'; return { displayValue, }; }, };
- 将组件注册到AgGridVue:
<AgGridVue :components="{ ButtonAgGrid }" ... />
- 配置列定义与响应式rowData计算属性:
const columnDefs = [ { field: "name" }, { field: "button", cellRenderer: "ButtonAgGrid", } ] const rowData = computed(() => { return { name: testReactiveValue.value ? 'test' : 'test2' } })
当rowData因testReactiveValue更新而变化时,AG Grid抛出错误:
Error: AG Grid: cannot get grid to draw rows when it is in the middle of drawing rows. Your code probably called a grid API method while the grid was in the render stage. To overcome this, put the API call into a timeout, e.g. instead of api.redrawRows(), call setTimeout(function() { api.redrawRows(); }, 0). To see what part of your code that caused the refresh check this stacktrace.
移除列定义中的cellRenderer: "ButtonAgGrid"后,报错消失,功能恢复正常。
1. 修正自定义组件的AG Grid适配规范
AG Grid的Vue单元格渲染组件必须接收框架传入的params参数,缺失该参数会导致渲染时序冲突。修改组件代码:
const ButtonAgGrid = { template: "<button>{{ displayValue }}</button>", props: ['params'], // 必须声明接收AG Grid传入的params对象 setup(props) { const displayValue = 'TEST-TEXT'; return { displayValue, }; }, };
2. 改用增量更新rowData而非全量替换
直接返回新的rowData对象会触发AG Grid全量重绘,容易引发时序问题。可改为直接修改现有响应式对象的属性:
// 初始化时创建响应式对象 const rowData = ref({ name: 'test' }); // 监听值变化,直接更新属性 watch(testReactiveValue, (newVal) => { rowData.value.name = newVal ? 'test' : 'test2'; });
3. 延迟rowData更新避开渲染阶段
若上述方法无效,可将更新逻辑放入setTimeout,避开AG Grid的渲染周期:
const rowData = ref({ name: 'test' }); watch(testReactiveValue, (newVal) => { setTimeout(() => { rowData.value = { name: newVal ? 'test' : 'test2' }; }, 0); });
4. 开启AG Grid的 immutable 数据模式
在AgGridVue组件中启用immutable-data,让框架更高效处理数据变化,减少重绘冲突:
<AgGridVue :components="{ ButtonAgGrid }" :immutable-data="true" ... />
内容的提问来源于stack exchange,提问作者Andrii Berezhnyi

