el-table项目使用场景

396 阅读2分钟
场景一:表格多选回显
  • 表格属性table attributes: row-key
    表格方法methods: select-change; toggleRowSelection clearSelection
    表格列属性table-column attributes: reserve-selection: true 则会在数据更新之后保留之前选中的数据(需指定 row-key
  • 表格数据分页查询的列表 tableList 查询获得的相当于已经选中的列表需要回显选中的addedList
  • 使用toggleRowSelection初始选中addedListtableList的交集,之后的勾选与反选会形成一个保留所选数据的新的集合multiList,切换分页时需要剔除multiList中包含addedList的元素,剩下的元素与addedList合并,再与分页查询的列表 tableList交集,通过toggleRowSelection选中当前页的数据
  // 多选
  handleSelectionChange (val, row) {
    this.multipleSelection = val;
  },
  // row-key绑定id
  getRowKeys (row) {
    return row.id
  },
  // 选中记忆
  rowChecked(addedArr) {
    addedArr = addedArr || []
    if(addedArr && addedArr.length > 0) {
      addedArr.forEach((item, index) => {
        this.tableList.forEach((itemChecked, iChecked) => {
          if (item.id === itemChecked.id) {
            this.$refs.multipleTable.toggleRowSelection(this.tableList[iChecked], true);
          }
        })
      })
    }
  },
  // 是否勾选对比过滤
  mergeSelected () {
    let tmpMultiSelected = [];
    let multiSelected = this.multipleSelection
    if (this.addedList && this.addedList.length > 0) {
      if (multiSelected && multiSelected.length > 0) {
        multiSelected.forEach(item => {
          this.addedList.forEach(itemChecked => {
            if (item.id !== itemChecked.id) {
              tmpMultiSelected.push(item);
            }
          })
        })
      }
      tmpMultiSelected = [...this.addedList, ...tmpMultiSelected];
    } else {
      tmpMultiSelected = this.multipleSelection;
    }
    return tmpMultiSelected
  },
  // 处理分页
  handleSizeChange (val) {
    this.pageSize = val;
    let tmpMultiSelected = this.mergeSelected()
    this.addedList = [...];
    setTimeout(() => {
      this.rowChecked(_this, tmpMultiSelected)
    }, 500);
  },

此方案实现的问题:会始终保留addedList在每次分页查询中的结果,当用户反选掉之后,不断切换分页,反选操作其实是无效的,如果只是为了追加新的多选数据,那可以在分页的时候把addedList过滤掉,那么这时候用户的勾选反选和保留之前选中的数据的选中状态所得出来的结果是符合用户操作逻辑的。

场景二:多选表格分列合并
  • 表格属性table attributes: span-method
  • 准备数据spanArr: 存放每一行记录的合并数 pos: 合并位置索引spanArr: [3, 0, 0, 1]假设第一列才合并,那么此处代表1列的第1-3行合并,第四行独占一行
  • 返回数据[rowspan, colspan]{ rowspan: 0, colspan: 0 }
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  // columnIndex为0是第一列空间类型合并,1和2为空间名称和空间did合并
  const mergeSpacetypeRow = this.spacetypeSpanArr[rowIndex];
  const mergeSpacetypeCol = mergeSpacetypeRow > 0 ? 1 : 0;
  const mergeSpaceRow = this.spaceSpanArr[rowIndex];
  const mergeSpaceCol = mergeSpaceRow > 0 ? 1 : 0;
  if (columnIndex === 0) {
    return {
      rowspan: mergeSpacetypeRow,
      colspan: mergeSpacetypeCol
    };
  } else if (columnIndex === 1 || columnIndex === 2) {
    return {
      rowspan: mergeSpaceRow,
      colspan: mergeSpaceCol
    };
  }
},
  getSpanArr(data) {
    // 空间类型位置合并数组
    this.spacetypeSpanArr = [];
    // 空间合并数组
    this.spaceSpanArr = [];
    // 空间类型合并位置记录点
    this.spacetypePos = 0;
    // 空间位置合并点
    this.spacePos = 0;
    for (let i = 0; i < data.length; i++) {
      if (i === 0) {
        this.spacetypeSpanArr.push(1); // 第一行先占一行
        this.spaceSpanArr.push(1);
        this.spacetypePos = 0;  // 记录位置索引为0
        this.spacePos = 0;
      } else {
        if (data[i].spacetypename === data[i - 1].spacetypename) {
          this.spacetypeSpanArr[this.spacetypePos] += 1; // 当前行与上一行合并增加一行
          this.spacetypeSpanArr.push(0); // 当前行不显示
        } else {
          this.spacetypeSpanArr.push(1); // 当前行与上一行不同,当前行占一行
          this.spacetypePos = i;  // 更新位置索引为当前索引
        }
        if (data[i].space_did === data[i - 1].space_did) {
          this.spaceSpanArr[this.spacePos] += 1;
          this.spaceSpanArr.push(0);
        } else {
          this.spaceSpanArr.push(1);
          this.spacePos = i;
        }
      }
    }
  }
场景三:展开收起懒加载
  • 表格属性table attributes: row-key; lazy: true; load: fn; tree-props: { hasChildren: 'hasChildren', children: 'children' }
  • 准备树形数据,父子结构数据基本格式相同,将父级所在的children数据预先挂在一个新的自定义属性,与tree-propschildren名称不一致
  • load方法中包含三个参数,对于有子级数据的当前行,通过resolve传递当前行字定义属性的children值即可懒加载展开子级数据
  • 不懒加载和懒加载的数据结构体现为hasChildrenchildren两属性分别有其一才可
// 树形数据
let data = [];
modules.forEach(val => {
  let children = [];
  val.products.forEach(v => {
    children.push({
      name: v.name,
      vtpid: v.pid,
      create: 0,
      flag: 1
    });
  });
  data.push({
    vtpid: val.id,
    name: val.name,
    create: '',
    hasChildren: true ? undefined : true, // 不懒加载和懒加载两属性分别有其一才可
    products: children, // 父级所在的children数据预先挂在一个新的自定义属性,后续调用load函数时通过resolve(tree.products),也就是自己数据
    children: true ? children : undefined, // 不懒加载和懒加载两属性分别有其一才可
    flag: 0
  });
});
load(tree, treeNode, resolve) {
  resolve(tree.products); // 当前行存的子级数据展开
}