美文网首页
使用原生table和vue来书写复合表头

使用原生table和vue来书写复合表头

作者: 糖小羊儿 | 来源:发表于2021-05-21 15:45 被阅读0次

    在工作上遇到一个复合表头,但是又因为需求比较特殊,不能使用element-ui这类ui的table组件,没办法硬着头皮上了

    image.png
    <template>
      <div class="zz-dynamic-table">
        <table class="customTable" border="0" cellpadding="0" cellspacing="0">
          <tr v-for="(aitem, i) in newTheadData" :key="'a' + i">
            <th width="40" :rowspan="rows" v-if="i == 0">
              <i @click="addRow" class="el-icon-plus"></i>
            </th>
            <th
              v-for="(bitem, j) in aitem"
              :key="'b' + j"
              :rowspan="bitem.rowspan"
              :colspan="bitem.colspan"
              v-html="bitem.label"
            ></th>
          </tr>
        </table>
      </div>
    </template>
    <script>
    import formItem from "../label-form/form-item";
    export default {
      name: "zz-dynamic-table",
      components: {
        formItem,
      },
      props: {
        theadData: {
          type: Array,
          default: () => [
                { key: "date", label: "日期",type:'input' },
                { label: "配送信息",children:[
                    { key: "name", label: "姓名",type:'input'},
                    { label: "地址",children:[
                        { key: "province", label: "省份",type:'input'},
                        { key: "city", label: "市区",type:'input'},
                        { key: "address", label: "详细<br/>地址",type:'input'},
                    ]},
                ]},
                { key: "zip", label: "编码" },
            ],
        },
      },
      data() {
        return {
          rows: 1,
          tableData: [],
          newTheadData: [],
        };
      },
      created() {
        this.newTheadData = this.getTheadData(this.theadData);
      },
      methods: {
        //获取最终结果返出去
        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></style>
    

    相关文章

      网友评论

          本文标题:使用原生table和vue来书写复合表头

          本文链接:https://www.haomeiwen.com/subject/svmwjltx.html