element-plus使用虚拟化表格报错:Failed to execute ‘querySelectorAll‘ on ‘Element‘: ‘[rowke

673 阅读2分钟

问题说明

本次更新项目,也将项目中的element-plus升级至最新版本,但在升级后使用虚拟化表格组件el-table-v2出现了问题,数据可正常展示,但当鼠标在表格上经过时,控制台就会不断报错,分别有黄色警告和红色报错,内容如下:

    Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Element': '[rowkey=1]' is not a valid selector.
        at onRowHovered (http://192.168.25.183:5173/node_modules/.vite/deps/element-plus.js?v=b7a41fa6:49168:28)
        at handlerMosueEnter (http://192.168.25.183:5173/node_modules/.vite/deps/element-plus.js?v=b7a41fa6:50564:35)
        at callWithErrorHandling (http://192.168.25.183:5173/node_modules/.vite/deps/chunk-R5FCYZP3.js?v=b7a41fa6:1659:19)
        at callWithAsyncErrorHandling (http://192.168.25.183:5173/node_modules/.vite/deps/chunk-R5FCYZP3.js?v=b7a41fa6:1666:17)
        at HTMLDivElement.invoker (http://192.168.25.183:5173/node_modules/.vite/deps/chunk-R5FCYZP3.js?v=b7a41fa6:10297:5)

报错截图:

err2.png 当前使用的版本:

  "node": "^20.12.2",
  "element-plus": "^2.7.3",
  "vue": "^3.4.27",
  "vite": "^5.2.11",

关于虚拟化表格组件el-table-v2的使用可以看我之前的这篇文章: element-plus虚拟化表格组件el-table-v2渲染自定义组件的其中两种方式(js和jsx)及注意事项,同样的代码,之前是没有报错的。

经排查后发现原因如下

这与绑定的id字段值有关系,通常情况下,获取数据时会有一个字段名为id,如果此时id字段的值为纯数字、数字字符串或是GUID类型的值(如果发现还有其他类型的,也可补充),即便是在页面上不展示这个字段,也会有这个报错。组件本身可能默认使用了id值作为querySelectorAll的传入参数

1.JPG

解决办法

  1. 更换element-plus版本;
  2. 将id的值重新设置,比如数字加字母的组合,只要不是会报错的值的类型就可以;
  3. 如果页面上要展示这个id字段的值,可以新建一个字段比如ids,将id的值赋给它,然后删除id字段,这种数据处理前端做也行,后端做也行,这里以前端示例:

2.JPG

<template>
  <div class="">
    <el-table-v2 :columns="columns" :data="tableData" fixed />
  </div>
</template>

<script setup>
import { ref } from "vue";

const columns = [
  {
    key: "ids", //版本2.7.3时,如果key的值是id,则不能为纯数字或数字字符串,不然会报错,如果需要展示则建议使用其他字段
    dataKey: "ids", //需要渲染当前列的数据字段,如{ids:9527,name:'Mike'},则填ids
    title: "ID", //显示在单元格表头的文本
    width: 80, //当前列的宽度,必须设置
    fixed: true, //是否固定列
  },
  {
    key: "name",
    dataKey: "name",
    title: "姓名",
    width: 150,
  }
];
//假设获取到后端返回数据如下(这里简单示例)
let list = [
  {
    id: 1,
    name: "Mike",
    ...
  },
  {
    id: 2,
    name: "Tom",
    ...
  },
];
let tableData = ref([]);
tableData.value = list.map(item=>{
    item['ids']=item.id;
    delete item.id;
    return item;
});
</script>