Vxetable v3.6.9 合并单元格+虚拟滚动问题

Vxetable v3.6.9 合并单元格+虚拟滚动问题

使用版本

vue:2.7.16

vxe-table:3.6.9

下面示例使用的是:scroll-y="{}":merge-cells="{}" 方式

重要说明 本案例使用的的版本比较老,因为是老项目。官网连接:Vxe Table v3.8

示例:这里使用 虚拟滚动+ 合并单元格单元格方式

需求说明:实现根据层级实现一对多合并单元格,并且数据量大

说明:这里代码示例是使用的项目中封装方法。
封装组件ElXTable/index.vue

vue 复制代码
<template>
  <vxe-table
    id="eTable"
    ref="singleTable"
    class="my-vxe-table"
    :scroll-y="{ enabled: isVirtual, gt: 0, mode: 'wheel', ...scrollY }"
    :height="height"
    :data="pageData.data || dataList"
    border
    show-overflow
    keep-source
    :row-id="rowKey"
    size="medium"
    :merge-cells="mergeCells"
    >
    <slot />
  </vxe-table>
  // 分页
  <vxe-pager
    :hide-on-single-page="false"
    :current-page="pageData.currentPage"
    :page-sizes="[50, 100, 200, 500, 1000]"
    :page-size="pageData.pageSize"
    size="small"
    :pager-count="5"
    :layouts="['Total', 'Sizes', 'PrevPage', 'JumpNumber', 'NextPage', 'FullJump']"
    :total="pageData.total"
    @page-change="handleCurrentChange"
  />
  </div>
</template>
<script>
export default {
  methods:{
    // 获取当前表格的列 {collectColumn, fullColumn, visibleColumn, tableColumn}
    getTableColumn() {
      return this.$refs.singleTable.getTableColumn().fullColumn
    },
    
    // 获取表格的可视的列 Array (及不包含隐藏的列 - 工具栏隐藏功能)
    getColumns() {
      return this.$refs.singleTable.getColumns()
    }
  }
}
</script>
 

page/index.vue

vue 复制代码
<template>
    <ElXTable
        ref="xTable"
        isVirtual
        rowKey="id"
        :dataList="tableData"
        :mergeCells="mergeCells"
    >
        <vxe-column type="checkbox" width="60" />
        <vxe-column type="seq" title="序号" width="55" />
        <vxe-column field="data1" title="数据1"></vxe-column>
        ...
    </ElXTable>
</template>
<script>
import ElXTable from "@/components/ElXTable"
export default {
  components: {
    ElXTable
  },
  data() {
    return {
      tableData: [],  // 表格数据 
      mergeCells: [], // 合并单后数据
      // 字段层级分类
      propertyLvObj: {
        l1: ["data1", ...],
        l2: [...],
        l3: [...],
        l4: [...]
      },
    }
  },
  mounted() {
      this.getTableData()
  },
  methods: {
      //获取表格数据
      getTableData(){
          // 这里调用接口
          const res = await $https.getVerifyPlan()
          if (res) {
            this.tableData = res.records
            this.getMergeCells(res.records)
          }
      },
     getMergeCells(data) {
      let column = this.$refs.xTable.getColumns()
      this.mergeCells = []
      this.tableData.forEach((row, _rowIndex) => {
        column.forEach((column, index) => {
          let r = this.spanMethod({ row, _rowIndex, column, data })
          if (r) {
            this.mergeCells.push({ ...r, row: _rowIndex, col: index })
          }
        })
      })
    },
    // 通用行合并函数(将相同多列数据合并为一行)
    /**
     *  思路 根据相邻行对应id 相同  才合并 需要注意的是 数据返回需要后端排序
     */
    spanMethod({ row, _rowIndex, column, data }) {
      // 需要合并的列
      const fields = []
      Object.keys(this.propertyLvObj).forEach((item) => {
        fields.push(...this.propertyLvObj[item])
      })
      const cellValue = row[column.property] // 当前行数据的值
      if (fields.includes(column.property)) {
        const prevRow = data[_rowIndex - 1] // 上一行数据
        let nextRow = data[_rowIndex + 1] // 下一行数据
        if (prevRow && fields.includes(column.property) && this.filterFields(row, prevRow, column.property)) {
          return { rowspan: 0, colspan: 0 }
        } else {
          let countRowspan = 1
          while (nextRow && fields.includes(column.property) && this.filterFields(row, nextRow, column.property)) {
            nextRow = data[++countRowspan + _rowIndex]
          }
          if (countRowspan > 1) {
            return { rowspan: countRowspan, colspan: 1 }
          }
        }
      }
    },

     /**
     *  特定的字段列 判断条件不一样
     *  根据相邻行数据前面的 mergeId1、mergeId2 来判断是否相同
     */
    filterFields(currRow, row, property) {
      if (this.propertyLvObj["l1"].includes(property) && currRow["mergeId1"] === row["mergeId1"]) {
        return true
      }
      if (this.propertyLvObj["l2"].includes(property) && currRow["mergeId2"] === row["mergeId2"]) {
        return true
      }
      if (this.propertyLvObj["l3"].includes(property) && currRow["mergeId3"] === row["mergeId3"]) {
        return true
      }
      if (this.propertyLvObj["l4"].includes(property) && currRow["mergeId4"] === row["mergeId4"]) {
        return true
      }
      return false
    },
  }
}
</script>

这里重点说明下官网 vxetable3.0版本 的虚拟滚动和合并单元不能同时使用问题。官网说的不能同时使用合并方法使用的是自定义 span-method合并方法。如果是数据量小不需要虚拟滚动建议使用。除此以外建议使用merge-cells

相关推荐
curdcv_po7 分钟前
🔥🔥🔥结合 vue 或 react,去写three.js
前端·react.js·three.js
猫头_35 分钟前
uni-app 转微信小程序 · 避坑与实战全记录
前端·微信小程序·uni-app
天生我材必有用_吴用38 分钟前
网页接入弹窗客服功能的完整实现(Vue3 + WebSocket预备方案)
前端
海拥43 分钟前
8 Ball Pool:在浏览器里打一局酣畅淋漓的桌球!
前端
Cache技术分享1 小时前
148. Java Lambda 表达式 - 捕获局部变量
前端·后端
YGY Webgis糕手之路1 小时前
Cesium 快速入门(二)底图更换
前端·经验分享·笔记·vue
神仙别闹1 小时前
基于JSP+MySQL 实现(Web)毕业设计题目收集系统
java·前端·mysql
前端李二牛1 小时前
Web字体使用最佳实践
前端·http
YGY_Webgis糕手之路1 小时前
Cesium 快速入门(六)实体类型介绍
前端·gis·cesium
Jacob02341 小时前
UI 代码不写也行?我用 MCP Server 和 ShadCN 自动生成前端界面
前端·llm·ai编程