关于javascript:vue-原生table组件封装

6次阅读

共计 3010 个字符,预计需要花费 8 分钟才能阅读完成。

<template>
  <div class="zz-dynamic-table">
    <table class="customTable" border cellpadding="0" cellspacing="0">
      <thead>
        <tr v-for="(aitem, i) in newTheadData" :key="'a' + i">
          <th
            :width="bitem.width ? bitem.width :'auto'":style="{width: bitem.width ? bitem.width : 'auto', 'text-align': bitem.align ? bitem.align : 'center'}"v-for="(bitem, j) in aitem":key="'b'+ j"
            :rowspan="bitem.rowspan"
            :colspan="bitem.colspan"
            v-html="bitem.label"
          ></th>
        </tr>
      </thead>
      <tr v-for="(item, index) in tableData" :key="index">
        <td
          v-for="(item1, key, index1) in item"
          :key="index1"
          :align="thArr[index1].align && key === thArr[index1].key ? thArr[index1].align :'center'"
        >
          {{item1}}
        </td>
      </tr>
    </table>
  </div>
</template>
<script>
export default {
  name: 'zz-dynamic-table',
  props: {
    theadData: {
      type: Array,
      default: () => [{ key: 'date', label: '日期', align: 'left'},
        {
          label: '配送信息',
          children: [{ key: 'name', label: '姓名'},
            {
              label: '地址',
              children: [{ key: 'province', label: '省份'},
                {key: 'city', label: '市区'},
                {key: 'address', label: '具体 <br/> 地址'}
              ]
            }
          ]
        },
        {key: 'zip', label: '编码'}
      ]
    }
  },
  data() {
    return {thArr: [],
      rows: 1,
      tableData: [
        {
          date: '323232',
          name: 'wang',
          province: 'province',
          city: 'city',
          address: 'address',
          zip: 333
        },
        {
          date: '32323221',
          name: 'wang1',
          province: 'province1',
          city: 'city11',
          address: 'address1',
          zip: 555
        }
      ],
      newTheadData: []}
  },
  created() {this.newTheadData = this.getTheadData(this.theadData)
    // console.log('newTheadData=', this.newTheadData, this.rows)
    this.thArr = this.treeToFlat(this.theadData, [])
    console.log('thArr=', this.thArr)
  },
  methods: {treeToFlat(arr, res) {
      let result = res
      arr.forEach(item => {if (item.children?.length) {this.treeToFlat(item.children, result)
        } else {result.push(item)
        }
      })
      return result
    },
    // 获取最终后果返进来
    getTableData() {this.$nextTick(() => {
        let result = ''
        if (this.tableData && this.tableData.length) {result = JSON.stringify(this.tableData)
        }
        this.$emit('input', result)
      })
    },
    addRow() {this.tableData.push({})
    },
    // 数组中是否有 children 字段
    isHaveChildren(arr) {if (!arr) {return false}
      for (let i = 0; i < arr.length; i++) {let item = arr[i]
        if (item.children && item.children.length) {return true}
      }
      return false
    },
    // 获取该列合并的总数
    getColCount(data) {
      let sum = 0
      if (!data) {return sum}
      if (!data.children) {return sum}
      let _this = this
      let fn = function(arr) {if (!arr) {return sum}
        arr.forEach(item => {if (item.children) {fn(item.children)
          } else {sum++}
        })
      }
      fn(data.children)
      return sum
    },
    // 重组 thead 数据
    getTheadData(p) {let params = JSON.parse(JSON.stringify(p))
      if (!params) {return []
      }
      let data = [],
        _this = this
      var fn = function(arr) {if (!arr) {return []
        }
        // 是否领有多级表头
        let rowData = []
        if (_this.isHaveChildren(arr)) {
          arr.forEach(item => {if (item.children) {
              item.rowspan = 1
              item.colspan = _this.getColCount(item)
              fn(item.children)
            } else {
              item.rowspan = arr.length
              item.colspan = 1
            }
            rowData.push(item)
          })
        } else {
          arr.forEach(item => {
            item.rowspan = 1
            item.colspan = 1
            rowData.push(item)
          })
        }
        data.unshift(rowData)
      }
      if (this.isHaveChildren(params)) {
        // 重组
        this.rows = params.length
        fn(params)
      } else {
        // 不重组
        data.push(params)
      }
      return data
    }
  },
  watch: {theadData(value) {this.newTheadData = this.getTheadData(value)
    }
  }
}
</script>
<style lang="less" scoped>
.zz-dynamic-table {width: 100%;}
table {
  width: 100%;
  border-color: #777;
  // border-color: red;
}
thead {background: #eee;}
tr {width: 100%;}
th {
  padding: 3px 2px;
  min-width: 10%;
}
td {padding: 3px 2px;}
</style>

正文完
 0