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

相关推荐
Henrii_历小海5 分钟前
WhatsApp Web 不是手机镜像:多设备协议、本地数据流与出海获客流水线
前端·智能手机
ayqy贾杰13 分钟前
Claude Fable 5 提示词泄漏,抓紧学习下
前端·后端·面试
To_OC8 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic9 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy9 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志9 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble10 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯11 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜12 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司12 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能