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

相关推荐
源力祁老师4 小时前
Odoo 19 制造与会计集成深度解析
前端·javascript·制造
iFlow_AI4 小时前
iFlow CLI Hooks 「从入门到实战」应用指南
开发语言·前端·javascript·人工智能·ai·iflow·iflow cli
漂流瓶jz5 小时前
SourceMap数据生成核心原理:简化字段与Base64VLQ编码
前端·javascript·算法
桜吹雪5 小时前
手搓一个简易Agent
前端·人工智能·后端
诸葛老刘5 小时前
前端 css中的函数
前端·css
谢尔登5 小时前
通用会话控制方案
前端·网络协议·tcp/ip·react.js·gitlab
惜茶5 小时前
websocket操作入门
前端·javascript·websocket
摇滚侠6 小时前
Vue 项目实战《尚医通》,获取当前账户就诊人信息并展示出来,笔记42
前端·javascript·vue.js·笔记·html5
han_6 小时前
前端高频面试题之Vue-router篇
前端·vue.js·面试
C.果栗子6 小时前
Blob格式的PDF文件调用打印,浏览器文件打印(兼容)
前端·javascript·pdf