【Vue2 + ElementUI】el-table动态合并行和列

该文章展示了一个使用ElementUI库创建的表格组件示例,其中包含了单元格合并功能,数据是假定的,实际应用中应替换为接口数据。同时,文章还提及了一个Echarts饼图,用于显示不同类型的统计数据。
摘要由CSDN通过智能技术生成

实现:ElementUI + 假数据(使用时替换为接口数据即可)

一. 效果图

在这里插入图片描述

二. 代码

<template>
  <div class="table-wrap">
    <el-table
      :data="tableData"
      :span-method="handleSpanMethod"
      :cell-style="{ background: '#FFFFFF' }"
      border
      style="width: 100%"
    >
      <el-table-column prop="arealame" label="景区名称" align="center" />
      <el-table-column prop="type" label="行业类型" align="center" />
      <el-table-column prop="planceName" label="行业场所" align="center" />
      <el-table-column prop="scenicPersonCount" label="从业人员" align="center" />
      <el-table-column prop="cameracount" label="摄像头" align="center" />
      <el-table-column prop="scenicArchivescount" label="处罚信息" align="center" />
      <el-table-column prop="punishCount" label="案事件" align="center" />
      <el-table-column prop="personalizeCount" label="个性化" align="center" />
      
    </el-table>
  </div>
</template>
 
<script>
export default {
  name: 'CellMerge',
  data() {
    return {
      tableData: [],
      // 合并单元格
      arealameArr: [], // arealame
      arealameIndex: 0, // arealame索引
      typeArr: [], // type
      typeIndex: 0, // type索引
      planceNameArr: [], // planceName
      planceNameIndex: 0, // planceName索引
      scenicPersonCountArr: [], // scenicPersonCount
      scenicPersonCountIndex: 0, // scenicPersonCount
      cameracountArr: [], // cameracount
      cameracountIndex: 0, // cameracount索引
      scenicArchivescountArr: [], // scenicArchivescount
      scenicArchivescountIndex: 0 // scenicArchivescount索引
    }
  },
  mounted() {
    this.initTableData()
  },
  methods: {
    // 初始化表格数据
    initTableData() {
      const newTableData = [
        {
          'arealame': '台儿庄景区',
          'industryTypevoList': [
            {
              'type':"美食",
              'industrystatisticsvolist': [
                {
                  'planceName': '1001',
                  'scenicPersonCount': '88801',
                  'cameracount': '99901',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                },
                {
                  'planceName': '1002',
                  'scenicPersonCount': '88802',
                  'cameracount': '99902',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                },
                {
                  'planceName': '1003',
                  'scenicPersonCount': '88803',
                  'cameracount': '99903',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                }
              ]
            },
          ]
        },
        {
          'arealame': '铁道游击队',
          'industryTypevoList': [
            {
              'type':"宾馆1",
              'industrystatisticsvolist': [
                {
                  'planceName': '1001',
                  'scenicPersonCount': '88801',
                  'cameracount': '99901',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                },
                {
                  'planceName': '1002',
                  'scenicPersonCount': '88802',
                  'cameracount': '99902',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                },
                {
                  'planceName': '1003',
                  'scenicPersonCount': '88803',
                  'cameracount': '99903',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                }
              ]
            },
            {
              'type':"宾馆2",
              'industrystatisticsvolist': [
                {
                  'planceName': '1001',
                  'scenicPersonCount': '88801',
                  'cameracount': '99901',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                },
                {
                  'planceName': '1002',
                  'scenicPersonCount': '88802',
                  'cameracount': '99902',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                },
                {
                  'planceName': '1003',
                  'scenicPersonCount': '88803',
                  'cameracount': '99903',
                  'scenicArchivescount': '6',
                  'punishCount': '7',
                  'personalizeCount': '8',
                }
              ]
            },
          ]
        },
      ]
      this.tableData = []
      newTableData.map((res, index) => {
        const parentId = index
        this.tableData.push.apply(
          this.tableData,
          this.handleData([res], parentId)
        )
      })
      this.mergeTable(this.tableData)
    },
    // table 表格数据初始化处理,将树结构数据转为一维数组
    handleData(data, parentId) {
      data.map((res, index) => {
        var obj = {
          id: parentId
        }
        for (const key in res) {
          const isarr = Object.values(res).find((age) => {
            return Array.isArray(age)
          })
          if (isarr) {
            if (Array.isArray(res[key])) {
              for (let i = 0; i < res[key].length; i++) {
                Object.assign(obj, res[key][i])
                data.push(obj)
                res[key].splice(i, 1)
                if (res[key].length === 0) {
                  data.splice(index, 1)
                }
                this.handleData(data, parentId)
              }
            } else {
              Object.assign(obj, { [key]: res[key] })
            }
          }
        }
      })
      return data
    },
    // 初始化合并行数组
    mergeInit() {
      this.arealameArr = [] // arealame
      this.arealameIndex = 0 // arealame索引
      this.typeArr = [] // type
      this.typeIndex = 0 // type索引
      this.planceNameArr = [] // planceName
      this.planceNameIndex = 0 // planceName索引
      this.scenicPersonCountArr = [] // scenicPersonCount
      this.scenicPersonCountIndex = 0 // scenicPersonCount索引
      this.cameracountArr = [] // cameracount
      this.cameracountIndex = 0 // cameracount索引
      this.scenicArchivescountArr = [] // scenicArchivescount
      this.scenicArchivescountIndex = 0 // scenicArchivescount索引
    },
    // 合并表格
    mergeTable(data) {
      this.mergeInit()
      if (data.length > 0) {
        for (var i = 0; i < data.length; i++) {
          if (i === 0) {
            // 第一行必须存在,以第一行为基准
            this.arealameArr.push(1) // arealame
            this.arealameIndex = 0
 
            this.typeArr.push(1) // type
            this.typeIndex = 0
 
            this.planceNameArr.push(1) // planceName
            this.planceNameIndex = 0
 
            this.scenicPersonCountArr.push(1) // scenicPersonCount
            this.scenicPersonCountIndex = 0
 
            this.cameracountArr.push(1) // cameracount
            this.cameracountIndex = 0
 
            this.scenicArchivescountArr.push(1) // scenicArchivescount
            this.scenicArchivescountIndex = 0
          } else {
            // 判断当前元素与上一元素是否相同
            // arealame
            if (
              data[i].arealame === data[i - 1].arealame &&
              data[i].id === data[i - 1].id
            ) {
              this.arealameArr[this.arealameIndex] += 1
              this.arealameArr.push(0)
            } else {
              this.arealameArr.push(1)
              this.arealameIndex = i
            }
 
            // type
            if (
              data[i].type === data[i - 1].type &&
              data[i].id === data[i - 1].id
            ) {
              this.typeArr[this.typeIndex] += 1
              this.typeArr.push(0)
            } else {
              this.typeArr.push(1)
              this.typeIndex = i
            }
 
            // planceName
            if (
              data[i].planceName === data[i - 1].planceName &&
              data[i].id === data[i - 1].id
            ) {
              this.planceNameArr[this.planceNameIndex] += 1
              this.planceNameArr.push(0)
            } else {
              this.planceNameArr.push(1)
              this.planceNameIndex = i
            }
 
            // scenicPersonCount
            if (
              data[i].scenicPersonCount === data[i - 1].scenicPersonCount &&
              data[i].id === data[i - 1].id
            ) {
              this.scenicPersonCountArr[this.scenicPersonCountIndex] += 1
              this.scenicPersonCountArr.push(0)
            } else {
              this.scenicPersonCountArr.push(1)
              this.scenicPersonCountIndex = i
            }
 
            // cameracount
            if (
              data[i].cameracount === data[i - 1].cameracount &&
              data[i].scenicPersonCount === data[i - 1].scenicPersonCount &&
              data[i].id === data[i - 1].id
            ) {
              this.cameracountArr[this.cameracountIndex] += 1
              this.cameracountArr.push(0)
            } else {
              this.cameracountArr.push(1)
              this.cameracountIndex = i
            }
 
            // scenicArchivescount
            if (
              data[i].scenicArchivescount === data[i - 1].scenicArchivescount &&
              data[i].scenicPersonCount === data[i - 1].scenicPersonCount &&
              data[i].id === data[i - 1].id
            ) {
              this.scenicArchivescountArr[this.scenicArchivescountIndex] += 1
              this.scenicArchivescountArr.push(0)
            } else {
              this.scenicArchivescountArr.push(1)
              this.scenicArchivescountIndex = i
            }
          }
        }
      }
    },
    handleSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0 ) {
        // 第一列 arealame
        const _row_1 = this.arealameArr[rowIndex]
        const _col_1 = _row_1 > 0 ? 1 : 0
        return {
          rowspan: _row_1,
          colspan: _col_1
        }
      } else if (columnIndex === 1) {
        // 第二列 type
        const _row_2 = this.typeArr[rowIndex]
        const _col_2 = _row_2 > 0 ? 1 : 0
        return {
          rowspan: _row_2,
          colspan: _col_2
        }
      } else if (columnIndex === 2) {
        // 第三列 planceName
        const _row_2 = this.planceNameArr[rowIndex]
        const _col_2 = _row_2 > 0 ? 1 : 0
        return {
          rowspan: _row_2,
          colspan: _col_2
        }
      } else if (columnIndex === 3) {
        // 第四列 scenicPersonCount
        const _row_2 = this.scenicPersonCountArr[rowIndex]
        const _col_2 = _row_2 > 0 ? 1 : 0
        return {
          rowspan: _row_2,
          colspan: _col_2
        }
      } else if (columnIndex === 4) {
        // 第五列 cameracount
        const _row_2 = this.cameracountArr[rowIndex]
        const _col_2 = _row_2 > 0 ? 1 : 0
        return {
          rowspan: _row_2,
          colspan: _col_2
        }
      } else if (columnIndex === 4) {
        // 第六列 scenicArchivescount
        const _row_2 = this.scenicArchivescountArr[rowIndex]
        const _col_2 = _row_2 > 0 ? 1 : 0
        return {
          rowspan: _row_2,
          colspan: _col_2
        }
      }
    }
  }
}
</script>
</style>

三. 隔行变色不生效

参考链接:https://segmentfault.com/a/1190000041320841

四. Echarts

在这里插入图片描述

option = {
  tooltip: {
    trigger: 'item'
  },
  legend: {
    top: '5%',
    left: 'center'
  },
  series: [
    {
      name: 'Access From',
      type: 'pie',
      radius: ['40%', '70%'],
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: '#fff',
        borderWidth: 2
      },
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: true,
          fontSize: 40,
          fontWeight: 'bold'
        }
      },
      labelLine: {
        show: false
      },
      data: [
        { value: 1048, name: '个性化' },
        { value: 735, name: '案事件' },
        { value: 580, name: '处罚信息' },
        { value: 484, name: '摄像头' },
        { value: 300, name: '从业人员' }
      ]
    }
  ]
};
要实现点击合并表格数据,需要使用 Element UI 提供的表格组件和相关 API。以下是一个基本的实现方法: 1. 定义表格的数据格式,包括表头和内容。 2. 在表格组件中使用 `table-row-class-name` 属性来设置的样式名。这个属性接受一个函数,函数的参数为当前的数据对象,返回值为这一的样式名。 3. 在样式名函数中,根据当前的数据对象判断是否需要和前一合并,如果需要合并,则返回一个特定样式名。 4. 使用 `span-method` 属性来定义合并单元格的方法。这个属性接受一个函数,函数的参数为当前单元格的列信息,返回值为一个包含 `rowspan` 和 `colspan` 属性的对象,用于指定合并数和列数。 下面是一个示例代码: ```html <template> <el-table :data="tableData" :row-class-name="rowClassName" :span-method="spanMethod"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <<el-table-column prop="gender" label="性别"></el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [ { name: '张三', age: 20, gender: '男' }, { name: '李四', age: 22, gender: '男' }, { name: '王五', age: 22, gender: '女' }, { name: '赵六', age: 25, gender: '女' }, ], }; }, methods: { rowClassName(row, index) { if (index > 0 && row.gender === this.tableData[index - 1].gender) { // 如果和前一性别相同,则需要合并 return 'merge-row'; } return ''; }, spanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 2 && rowIndex > 0 && row.gender === this.tableData[rowIndex - 1].gender) { // 如果是第三列,并且和前一性别相同,则需要合并 return { rowspan: 0, colspan: 0 }; } }, }, }; </script> <style> .merge-row td:nth-child(3) { /* 第三列需要合并 */ border-top-width: 0 !important; /* 去掉上边框 */ } </style> ``` 在上面的代码中,我们定义了一个表格,包含三列:姓名、年龄、性别。然后,我们使用 `row-class-name` 属性来设置的样式名,如果一需要和前一合并,则返回一个特定样式名。在样式中,我们设置第三列的单元格不显示上边框。最后,我们使用 `span-method` 属性来定义合并单元格的方法,如果一个单元格需要合并,则返回一个包含 `rowspan` 和 `colspan` 属性的对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值