【js-vue】基于element-ui表格封装合并行和列,可直接使用

// 子组件
<template>
  <!-- // 表格合并 -->
  <div class="sub-table">
    <div class="table-body-div table-body-div-no-border">
      <el-table
        :data="tableData"
        :span-method="objectSpanMethod"
        :cell-class-name="tableRowClassName"
        border
        style="width: 100%; margin-top: 20px;"
      >
        <template v-for="item in tableHeader">
          <el-table-column
            :key="`index-${item.prop}`"
            :prop="item.prop"
            :label="item.label"
            :width="item.width"
          >
            <template slot-scope="scope">
              <div style="display: flex;display: -webkit-flex;display: -ms-flex;-webkit-justify-content: center;-ms-justify-content: center;justify-content: center;flex-wrap: wrap;-webkit-flex-wrap: wrap;-ms-flex-wrap: wrap;">
                <slot name="tableBody" :value="scope.row" :prop="item.prop" :item="item" />
              </div>
            </template>
          </el-table-column>
        </template>
        <el-table-column
          v-if="isUseBar"
          :fixed="barFixed"
          :label="extraName"
          :width="barWidth"
          :align="barAlign ? barAlign : 'left'"
        >
          <template slot-scope="scope">
            <div style="display: flex;display: -webkit-flex;display: -ms-flex;-webkit-justify-content: center;-ms-justify-content: center;justify-content: center;flex-wrap: wrap;-webkit-flex-wrap: wrap;-ms-flex-wrap: wrap;">
              <slot name="tableColumn" :value="scope.row" />
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>
<script>
export default {
  name: 'TableView',
  props: {
    // 这个是处理合并的列和行的--以下是结构
    // {
    //   name: 0, // 需要处理的列数,第几列
    //   value: 'measureTime' // 需要处理合并的字段
    // }
    megreArray: {
      type: Array,
      default: () => {
        return []
      },
      require: true
    },
    // 表头
    tableHeader: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 数据
    tableDatas: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 这个是排序字段
    compareKey: {
      type: String,
      default: '',
      require: true
    },
    barWidth: {
      type: String,
      default: '140'
    },
    barFixed: {
      type: String,
      default: 'right'
    },
    barAlign: {
      type: String,
      default: 'center'
    },
    extraName: {
      type: String,
      default: function() {
        return '操作'
      }
    },
    isUseBar: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      orderIndexArr: [],
      lengthArray: [],
      hoverOrderArr: [],
      tableData: [],
      rowIndex: '-1'
    }
  },
  watch: {
    tableDatas(val) {
      this.tableData = val
      this.getOrderNumber(this.tableDatas, this.megreArray)
    }
  },
  created() {
    // 开始处理
    if (this.tableDatas) {
      this.tableData = this.tableDatas
      this.getOrderNumber(this.tableDatas, this.megreArray)
    }
  },
  methods: {
    // 获取相同编号的数组
    getOrderNumber(array, megree) {
      array = JSON.parse(JSON.stringify(array))
      this.orderIndexArr = []
      if (megree) {
        if (megree.length > 0) {
          // 先取第一个算出第一个合并的东西
          megree.forEach((svalue, aindex) => {
            if (aindex === 0) {
              const orderObj = {
                name: svalue.name,
                value: []
              }
              let temp = array
              temp = this.fn(temp, megree[0].value)
              temp.forEach(svaluea => {
                if (svaluea.data) {
                  // 排序
                  svaluea.data = svaluea.data.sort(this.compare(this.compareKey))
                }
              })
              // 处理之后temp处理成散数组
              const tempArrayList = []
              temp.forEach(svaluec => {
                if (svaluec.data) {
                  svaluec.data.forEach(gvalue => {
                    tempArrayList.push(gvalue)
                  })
                }
              })
              tempArrayList.forEach((item, index) => {
                item.rowIndex = index
                if (orderObj[item[svalue.value]]) {
                  orderObj[item[svalue.value]].push(index)
                } else {
                  orderObj[item[svalue.value]] = []
                  orderObj[item[svalue.value]].push(index)
                }
              })
              // 将数组长度大于1的值 存储到this.orderIndexArr(也就是需要合并的项)
              Object.keys(orderObj).forEach((key) => {
                if (orderObj[key].length > 1 && key !== 'value') {
                  orderObj.value.push(orderObj[key])
                }
              })
              this.orderIndexArr.push(orderObj)
            } else if (aindex > 0) {
              const orderObj = {
                name: svalue.name,
                value: []
              }
              // 如果超过两个,先对数组根据第一个megree来合并相同,并排序
              let temp = array
              temp = this.fn(temp, megree[0].value)
              temp.forEach((svaluea, indexa) => {
                if (svaluea.data) {
                  // 排序
                  svaluea.data = svaluea.data.sort(this.compare(this.compareKey))
                  // 处理为tableData的每一个megree对应的key值加上index。
                  svaluea.data.forEach(gvalue => {
                    gvalue[svalue.value] = gvalue[svalue.value] + indexa
                  })
                }
              })
              // 处理之后temp处理成散数组
              const tempArrayList = []
              temp.forEach(svaluec => {
                if (svaluec.data) {
                  svaluec.data.forEach(gvalue => {
                    tempArrayList.push(gvalue)
                  })
                }
              })
              // 在进行合并处理
              tempArrayList.forEach((item, index) => {
                item.rowIndex = index
                if (orderObj[item[svalue.value]]) {
                  orderObj[item[svalue.value]].push(index)
                } else {
                  orderObj[item[svalue.value]] = []
                  orderObj[item[svalue.value]].push(index)
                }
              })
              // 将数组长度大于1的值 存储到this.orderIndexArr(也就是需要合并的项)
              Object.keys(orderObj).forEach((key) => {
                if (orderObj[key].length > 1 && key !== 'value') {
                  orderObj.value.push(orderObj[key])
                }
              })
              this.orderIndexArr.push(orderObj)
            }
          })
        }
      }
    },
    compare(property) {
      return function(a, b) {
        var value1 = a[property]
        var value2 = b[property]
        // return value1.localeCompare(value2) // 这是字符串比较
        return value1 - value2
      }
    },
    /**
     * 先去重,后合并
     * 1、源数据去重
     * 2、把去重后的数据和源数据中相同name的数据合并citys
    */
    fn(data, keyValue) {
      const keySet = new Set(data.map(item => item[keyValue]))
      return Array.from(keySet).map(v => {
        return {
          key: v,
          data: data.filter(item => item[keyValue] === v)
        }
      })
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      for (let i = 0; i < this.orderIndexArr.length; i += 1) {
        if (columnIndex === this.orderIndexArr[i].name) {
          for (let s = 0; s < this.orderIndexArr[i].value.length; s += 1) {
            const element = this.orderIndexArr[i].value[s]
            for (let j = 0; j < element.length; j += 1) {
              const item = element[j]
              if (rowIndex === item) {
                if (j === 0) {
                  return {
                    rowspan: element.length,
                    colspan: 1
                  }
                }
                if (j !== 0) {
                  return {
                    rowspan: 0,
                    colspan: 0
                  }
                }
              }
            }
          }
        }
      }
    },
    // 算指定位数的求和
    qh(array, length) {
      let sum = 0
      for (let i = 0; i < length; i++) {
        sum += array[i]
      }
      return sum
    },
    tableRowClassName({ row, rowIndex }) {
      const arr = this.hoverOrderArr
      for (let i = 0; i < arr.length; i += 1) {
        if (rowIndex === arr[i]) {
          return 'hovered-row'
        }
      }
    },
    // 鼠标移入样式
    cellMouseEnter(row) {
      this.rowIndex = row.rowIndex
      this.hoverOrderArr = []
      this.orderIndexArr.forEach((element) => {
        if (element['value'] && element.name === 0) {
          element['value'].forEach(dvalue => {
            if (dvalue.indexOf(this.rowIndex) >= 0) {
              this.hoverOrderArr = dvalue
            }
          })
        }
      })
    },
    // 鼠标离开
    cellMouseLeave() {
      this.rowIndex = '-1'
      this.hoverOrderArr = []
    }
  }
}
</script>
<style>
.el-table .hovered-row {
    background: #f5f7fa;
 }
 .sub-table .el-image__error, .sub-table img{
    width:60px;
    height:60px;
    line-height: 60px;
 }
</style>
<style scoped lang="scss">
.sub-table{
    width:100%;
    height:auto;
    text-align: left;
}
</style>


// 父组件调用
<template>
  <div>
     <daily-record-hb-table
      :megre-array="megreArray"
      :table-header="dailyFoodListTable"
      :table-datas="dataValue"
      :compare-key="compareKey"
      :is-use-bar="isUseBar"
      style="margin-top:20px"
    >
      <template v-slot:tableBody="tableBody">
        <p>
          {{ tableBody.value[tableBody.prop] }}
        </p>
      </template>
    </daily-record-hb-table>
  </div>
</template>
<script>
import sHbTable from '@/components/DataTable/tableMerge'
export default {
  components: {
    'daily-record-hb-table': sHbTable
  },
  data(){
    megreArray: [
        {
          name: 0, // 需要处理的列数
          value: 'measureTime' // 需要处理的字段
        },
        {
          name: 1,
          value: 'MEALNameHb'
        }
      ],
      compareKey: 'MEAL',
      isUseBar: false,
      dailyFoodListTable: [],
      dataValue:[]
  }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沙滩上的一颗石头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值