前提
在开发过程中使用 vben 的 BasicTable组件进行页面功能实现,因设计需求页面在 table 中需要每行可点击从而显示对应的图标数据。所以需要给 table 中每行加上单选按钮。BasicTable设置如下,只要加上rowSelection即可。另外自带的点击事件为 @row-click="handleRowClick",但是这个点击事件只能点击表格主体而 radio 点击竟然没有效果。所以现在也要给 radio 加上点击事件。
出现问题
给 radio 加上点击事件不是很快嘛!直接在rowSelection中加上onChange即可。一顿操作猛如虎,运行后傻眼了。页面直接卡死崩溃了。
const handleRowSelectionChange = (keys) => {
const data = cloneDeep(fitTabeleData.value[keys[0] - 1]);
single_loop_capacity.value = data.image;
checkedKeys.value = [data.id];
};
功能很简单,就是点击当前行,然后根据index 获取数据,然后显示就好了。这里有个checkedKeys的赋值直接导致页面卡死。
解决问题
一开始想是页面更新问题,或者频繁点击的问题。那就给checkedKeys的赋值加上 nextTick并且给handleRowSelectionChange加上防抖。
const handleRowSelectionChange = debounce(([selectedKey]) => {
const selectedRow = fitTabeleData.value.find((row) => row.id === selectedKey) || {};
single_loop_capacity.value = selectedRow.image;
nextTick(() => {
checkedKeys.value = [selectedRow.id];
});
}, 100);
修改完之后有满怀信心的试了一下。不出所料,还是不行。没关系,上大招。那就判断一下当前选中的行 ID 是否已经存在于 checkedKeys.value 中。如果已经存在,那么就不需要再次更新 checkedKeys.value,从而避免触发不必要的重新渲染和可能的死循环。我不信这样还解决不了你!
const handleRowSelectionChange = debounce(([selectedKey]) => {
const selectedRow = fitTabeleData.value.find((row) => row.id === selectedKey) || {};
single_loop_capacity.value = selectedRow.image;
nextTick(() => {
if (checkedKeys.value[0] !== selectedRow.id) {
这一步是为了避免不必要的更新和重新渲染。具体来说,这个条件判断语句的作用是检查
checkedKeys.value = [selectedRow.id];
}
});
}, 100);
问题所在
其实就是checkedKeys.value中已经存在了id,但是还是修改了它的值。就导致触发了echats dom的渲染更新。而且因为渲染 echarts的数据比较大,所以页面承受不住就卡死了。