关于el-table调用清除方法clearSelection()时会触发change方法的解决方案

目录

      • 需求场景
      • 遇到的问题
      • 初步解决方案
      • 解决方案的关键点
      • 常见问题与解答

需求场景

在最近的一个项目中,我们需要实现一个账户切换功能。具体场景如下:
左侧账户切换:用户可以在左侧栏切换不同的账户。
表格数据展示:每个账户对应不同的数据,这些数据通过同一个 el-table 展示。
选中行的管理:在切换账户时,理想的操作是先清空当前表格中的选中行,然后根据切换后的账户,手动回显该账户之前保存的选中行。

遇到的问题

在实现上述需求时,我们遇到了一个问题:
问题描述:每次调用 clearSelection() 方法时,都会触发 change 事件。由于 change 事件在选中行变化时被触发,我们在 change 事件的回调函数中保存了选中行的数据。然而,调用 clearSelection() 清空选中行时,change 事件会将选中的值赋为空数组,导致之前保存的选中数据被清空,从而无法实现选中行的正确回显。

初步解决方案

为了解决上述问题,我们设计了一个方案:

  1. 添加标识位:在调用 clearSelection() 方法时,设置一个标识位(如 isChangeType),用于区分是用户主动触发的选中行变化,还是程序调用 clearSelection() 方法引发的选中行变化。
  2. 拦截 change 事件:在 change 事件的回调函数中,根据标识位判断是否需要处理选中行的变化。如果是程序调用的 clearSelection(),则不进行处理,避免将保存的选中数据清空。
  3. 回显选中行:在清空选中行后,手动回显之前保存的选中行数据。在此过程中,由于调用了 toggleRowSelection() 方法,同样会触发 change 事件。因此,需要对回显的选中行进行去重处理,避免重复数据的出现。
handleSelectionChange(value) {
 // isChangeType用来拦截因为调用clearSelection时出现haveselect的值被清空的情况。
      if (!this.isChangeType) {
        const unselectIds = _.cloneDeep(value);
        this.creativeOptions[this.currentType].haveSelect = this.unique(unselectIds);
      }
    },
    // 左部分切换类型
     // 切换账户类型时的处理函数
    getCurrentType: debounce(async function(val) {
      this.currentType = val;
      this.isChangeType = true; // 设置标识位,表示即将调用清空操作
      await this.$refs.adTable.clearSelection(); // 清空选中行
      this.showSelect(); // 回显选中行
      this.isChangeType = false; // 重置标识位
    }, 300), // 防抖时间300ms    // 回显已选
    
    showSelect() {
      const { haveSelect } = this.creativeOptions[this.currentType];
      for (let child of haveSelect) {
        for (let item of this.adData) {
          if (child.id == item.id) {
            this.$refs.adTable.$children[0].toggleRowSelection(item, true);
            item = child;
            break;
          }
        }
      }
    },
    // 数组对象去重操作
     unique(array) {
	  const seen = new Map();
	  return array.filter(item => {
	    const key = typeof item + JSON.stringify(item);
	    if (seen.has(key)) {
	      return false;
	    } else {
	      seen.set(key, true);
	      return true;
	    }
	  });
	},

解决方案的关键点

  1. 标识位控制:通过 isChangeType 标识位,区分是程序调用的 clearSelection() 还是用户主动的选中行变化。这样可以避免在程序调用清空选中行时,错误地处理 change 事件,导致已保存的选中数据被清空。

  2. 手动回显选中行:在清空选中行后,手动调用 toggleRowSelection() 方法选中之前保存的行数据。需要注意的是,调用 toggleRowSelection() 也会触发 change 事件,因此需要在 handleSelectionChange 方法中进行标识位的控制,防止误操作。

  3. 去重处理:由于 toggleRowSelection() 方法可能导致选中行数据重复,需要对选中行数据进行去重处理,确保数据的一致性和准确性。

常见问题与解答

在实际开发过程中,可能会遇到一些与本文主题相关的常见问题。以下列出部分常见问题及解答,帮助开发者更好地理解和应用相关解决方案。

问题1:clearSelection() 方法为什么会触发 selection-change 事件?
解答:clearSelection() 方法用于清除所有选中行,当调用该方法时,表格的选中行状态发生变化,因此会触发 selection-change 事件。事件回调函数中通常会处理选中行的数据,这可能会导致程序逻辑出现问题,如选中行数据被错误清空。

问题2:如何避免程序调用 clearSelection() 触发的 selection-change 事件干扰选中行数据?
解答:可以通过设置标识位(如 isChangeType)来区分是程序调用还是用户操作引起的选中行变化。在事件回调函数中,根据标识位判断是否需要处理选中行的数据,避免程序调用引起的不必要处理。

问题3:为什么手动回显选中行时会出现重复数据?
解答:手动回显选中行时,如果之前已经保存了选中行的数据,再次调用 toggleRowSelection() 方法会导致重复选中行。因此,需要对选中行的数据进行去重处理,确保数据的一致性和准确性。

问题4:如何在切换账户类型时保存当前选中行的数据?
解答:可以在切换账户类型前,调用一个方法(如 saveSelectedRows())将当前选中行的数据保存到后端或本地存储中。这样,在切换账户类型后,可以根据保存的数据,回显选中行,确保用户的操作数据不丢失。

问题5:如何优化表格的性能,避免频繁调用 toggleRowSelection() 导致性能问题?
解答:可以使用防抖或节流技术,限制 toggleRowSelection() 方法的调用频率。例如,在切换账户类型时,使用防抖函数延迟执行切换操作,避免由于频繁切换导致的性能问题。

问题6:如何动态配置表格的列,以适应不同账户类型的数据展示需求?
解答:可以根据账户类型,动态设置表格的列配置(如 tableColumns 数组)。在切换账户类型时,调用一个方法(如 setTableColumns(type))根据不同类型设置相应的列配置,从而动态展示不同的数据列。

你可能感兴趣的:(前端知识,vue.js,前端,javascript)