element-plus表格报错:ResizeObserver loop completed with undelivered notifications.
当我点击筛选的时候,就会报错
<template>
<div>
<el-button type="primary" @click="setTableData">设置数据</el-button>
<el-table
ref="normalTable"
:data="tableData"
style="width: 100%"
max-height="440px"
>
<el-table-column
v-for="(column, index) in tableDataOption"
:key="index"
:prop="column.prop"
:label="column.label"
:column-key="column.prop"
:filter-multiple="false"
:filters="column.filter ? column.filterOptions : null"
:filter-method="column.filter ? filterHandler : null"
/>
</el-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let tableData = ref<any[]>([])
const tableDataOption = ref<any[]>([])
const filterHandler = (value: any, row: any, column: any) => {
const property = column.property
return row[property] === value
}
function setTableData(){
setTimeout(()=>{
if(!tableDataOption.value?.length){
tableDataOption.value= [
{ "prop": "bucket",
"label": "桶名称",
"filter": true,
filterOptions: [
{ "text": "A1", "value": "A1" },
{ "text": "B1", "value": "B1" }
]
},
{
"prop": "projectID", "label": "企业项目", "filter": false,
}
]
}
tableData.value= [
{
"bucket": "bucket-1e1f",
"childInfo": [],
"projectID": "default",
"id": "bucket-1e1f",
"name": "bucket-1e1f",
"selectable": true,
"disabled": false,
},
{
"bucket": "bucket-272e",
"childInfo": [],
"projectID": "default",
"id": "bucket-272e",
"name": "bucket-272e",
"selectable": true,
"disabled": false,
},
]
},1300)
}
</script>
<style scoped>
</style>

原因分析:
filters 引发布局变化的主要原因;加了filters 后
表头会多渲染一个筛选 → 表头高度/行高变化 → 表格重新布局。
el-table 内部用 ResizeObserver 监听自身尺寸,
叠加你 1300ms 后异步灌数据的时机,
形成"尺寸变 → 触发 observer → 又改布局"的一帧内循环,浏览器就报这个错。
解决办法:给列宽设置宽度
<el-table-column
v-for="(column, index) in tableDataOption"
:key="index"
:prop="column.prop"
:label="column.label"
:min-width="150" // 通过设置列宽来解决这个问题哈
:column-key="column.prop"
:filter-multiple="false"
:filters="column.filter ? column.filterOptions : null"
:filter-method="column.filter ? filterHandler : null"
/>
不会报错的
有的小伙伴说:我下面的代码没有设置宽度,也没有报错。
所以不是你说的那个原因。
是因为你这个值的所占的宽度原因,并不是因为值哈
<template>
<div>
<el-button type="primary" @click="setTableData">设置数据</el-button>
<el-table
ref="normalTable"
:data="tableData"
style="width: 100%"
max-height="440px"
>
<el-table-column
v-for="(column, index) in tableDataOption"
:key="index"
:prop="column.prop"
:label="column.label"
:column-key="column.prop"
:filter-multiple="false"
:filters="column.filter ? column.filterOptions : null"
:filter-method="column.filter ? filterHandler : null"
/>
</el-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let tableData = ref<any[]>([])
const tableDataOption = ref<any[]>([])
const filterHandler = (value: any, row: any, column: any) => {
const property = column.property
return row[property] === value
}
function setTableData(){
setTimeout(()=>{
if(!tableDataOption.value?.length){
console.log('设置数据')
tableDataOption.value= [
{ "prop": "bucket",
"label": "桶名称",
"filter": true,
filterOptions: [
{ "text": "选项A", "value": "A1" },
{ "text": "选项B", "value": "B1" }
]
},
{
"prop": "projectID", "label": "企业项目", "filter": false,
}
]
}
tableData.value= [
{
// bucket的值是:bucket-1e1f,就会报错:
// ResizeObserver loop completed with undelivered notifications.
"bucket": "A111",
"childInfo": [],
"projectID": "default",
"id": "bucket-1e1f",
"name": "bucket-1e1f",
"selectable": true,
"disabled": false,
},
{
"bucket": "B11",
"childInfo": [],
"projectID": "default",
"id": "bucket-272e",
"name": "bucket-272e",
"selectable": true,
"disabled": false,
},
]
},1300)
}
</script>
根据上面的代码,是值"bucket": "bucket-1e1f"引起的?
答:不是。
根本原因是:值所占的宽度造成的哈
我使用AI,AI给的回复
ResizeObserver loop completed with undelivered notifications 不是你的代码报错,
也不是 Element Plus 崩了,它是浏览器(Chrome/Edge)抛出的警告级 error event。
Vite 的 error overlay 会捕获它弹遮罩,所以看起来像报错。
一句一句说
-
元素的尺寸一变,浏览器并不会立刻调用你的回调。
它先把这条变化「记一笔」放进一个待处理列表中,
等这一帧走到固定时刻,
再把列表里攒下的通知一次性交给回调去执行。
把通知交给回调执行的行为,就叫派发。
-
组件库的回调里会写样式。
el-table 那个 resizeListener 发现高度变了,
就调 doLayout(),去写 body 高度、列宽、还有是否要纵向滚动条。
这一写,元素尺寸又变了。
-
于是列表末尾又多了一笔。
但这一轮的派发还没结束:浏览器正在挨个通知回调,而你刚刚又制造出一条新通知。
-
浏览器到点收摊。
规范不允许它在一帧里无限循环下去(否则页面就卡死)。
所以循环到上限时,它把还没送出的通知留到下一帧,同时在帧末抛一个 error 事件,内容就是那句:
ResizeObserver loop completed with undelivered notifications.
用大白话再说一遍
通知刚送完,回调又改了尺寸,新的通知又记上了;
浏览器怕死循环,这一帧到点收摊,没送完的留到下一帧,并顺手报一句"本轮结束,我没送完"。
所以这条 message 本质上是一张收摊回执,不是"我崩了"。