多级表头表格组件

文章展示了如何在Vue.js中创建一个自定义表格组件,包括数据绑定、多级表头、行选择、分页功能以及各种事件监听器(如行点击、多选变化等)。组件接受props来配置表格样式和行为,并能处理复杂的数据结构。

表格源文件

index.vue

<template>
  <div class="my-table">
    <el-table ref="multilevelTable" :data="rows" :row-class-name="rowClassName" :row-style="rowStyle" border stripe
      :height="height" :max-height="tableHeight" @selection-change="onSelectionChange" @row-click="onRowClick"
      @row-dblclick="onRowDblclick" @current-change="onCurrentChange">
      <el-table-column type="selection" v-if="selectionShow" width="50" align="center" fixed="left" />
      <el-table-column type="index" v-if="indexShow" :width="indexWidth" align="center" fixed="left" label="序号" />
      <table-column v-for="(item, index) in headerTitle" :key="index" :headerTitle="item"></table-column>
    </el-table>
    <pagination v-if="paginationShow" :total="totalPage" :page.sync="filter.pageNum" :limit.sync="filter.pageSize"
      @pagination="onPagination" />
  </div>
</template>

<script>
  import TableColumn from "./tableColumn";
  export default {
    components: {
      TableColumn,
    },
    props: {
      headerTitle: {
        type: Array | Object,
        default () {
          return [];
        }
      },
      data: {
        type: Object,
        default () {
          return {};
        }
      },
      indexWidth: {
        type: Number,
        default: 50
      },
      height: [String, Number],
      filter: { // 过滤条件
        type: Object,
        default () {
          return {};
        }
      },
      paginationShow: { // 分页器展示
        type: Boolean,
        default: true,
      },
      selectionShow: { // 复选框展示
        type: Boolean,
        default: true,
      },
      indexShow: { // 序号列展示
        type: Boolean,
        default: true,
      },
      rowClassName: [String, Function],
      rowStyle: [Object, Function],
    },
    computed: {
      rows() {
        if (!this.data) {
          return [];
        }
        return this.data.rows || [];
      },
      totalPage() {
        if (!this.data) {
          return 0;
        }
        return this.data.total || 0;
      },
      tableHeight() {
        let recordNum = 10; // 分页大小
        if (this.maxHeight) {
          return this.maxHeight;
        }
        if (this.headerFixed && this.data && this.data.rows && this.data.rows.length > recordNum) {
          let scrollBarHeight = 18;
          let ivuTableSmallThHeight = 40; // small size 下的table表头单元格高度
          let ivuTableSmallTdHeight = 40; // small size 下的table表体单元格高度
          return ivuTableSmallThHeight + ivuTableSmallTdHeight * recordNum + scrollBarHeight;
        }
        return null;
      }
    },
    methods: {
      /**
       * 表格行多选事件
       * @param selection
       */
      onSelectionChange(selection) {
        this.$emit("selection-change", selection);
      },

      /**
       * 当某一行被点击时会触发该事件
       * @param row
       * @param column
       * @param event
       */
      onRowClick(row, column, event) {
        if (this.showRadio) {
          //赋值给radio
          this.stdGroupRadio = this.rows.indexOf(row);
        }
        if (this.showCheck) {
          //赋值给checked
          this.getTableRef().toggleRowSelection(row);
        }
        this.$emit("row-click", row, column, event);
      },

      /**
       * 当某一行被点击时会触发该事件
       * @param row
       * @param column
       * @param event
       */
      onRowDblclick(row, column, event) {
        this.$emit("row-dblclick", row, column, event);
      },

      /**
       * 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性
       * @param currentRow
       * @param oldCurrentRow
       */
      onCurrentChange(currentRow, oldCurrentRow) {
        this.$emit("current-change", currentRow, oldCurrentRow);
      },

      /**
       * 分页参数变更事件
       */
      onPagination() {
        this.$emit('pagination', arguments);
      },
    },
  };

</script>

单行源文件

<template>
  <el-table-column :prop="headerTitle.prop" :label="headerTitle.label" :fixed="headerTitle.fixed"
    :width="headerTitle.width" align="center">
    <template v-if="headerTitle.children">
      <table-column v-for="(item, index) in headerTitle.children" :key="index" :headerTitle="item">
      </table-column>
    </template>
  </el-table-column>
</template>

<script>
  export default {
    name: "TableColumn",
    props: {
      headerTitle: {
        type: Array | Object,
      },
    },
  };

</script>
<style scoped>
</style>

使用时

先引用

import MultilevelTable from "@/components/multilevelTable";

再注册

components: { MultilevelTable }

就可以用啦

<multilevel-table 
    :headerTitle="planStartDetailHeader" 
    :data="planStartDetailData" 
    :filter="planStartConPO"   
    @selection-change="planStartSelectionChange" 
    @pagination="pagePlanStartDetail">
</multilevel-table>

表头格式如下

[
    {
        "children": [
            {
                "prop": "toolPedestalType0",
                "fixed": "left",
                "label": "浇筑台座"
            }
        ],
        "label": "台座类型"
    },
    {
        "children": [
            {
                "prop": "startDate0",
                "width": "135",
                "label": "开始时间"
            },
            {
                "prop": "endDate0",
                "width": "135",
                "label": "结束时间"
            }
        ],
        "label": "钢筋笼吊装"
    },
    {
        "children": [
            {
                "prop": "startDate1",
                "width": "135",
                "label": "开始时间"
            },
            {
                "prop": "endDate1",
                "width": "135",
                "label": "结束时间"
            }
        ],
        "label": "模板安装"
    },
    {
        "children": [
            {
                "prop": "startDate2",
                "width": "135",
                "label": "开始时间"
            },
            {
                "prop": "endDate2",
                "width": "135",
                "label": "结束时间"
            }
        ],
        "label": "混凝土浇筑"
    }
]

表格内容如下

{
    "total": 2,
    "rows": [
        {
            "tempComponentId": "100",
            "componentId": "1630395483321143372",
            "endDate0": "2023-02-11 10:00:00",
            "startDate2": "2023-02-11 13:00:00",
            "startDate0": "2023-02-11 07:00:00",
            "toolPedestalType0": "9号制梁台座",
            "startDate1": "2023-02-11 10:00:00",
            "endDate1": "2023-02-11 12:00:00",
            "endDate2": "2023-02-11 19:00:00"
        },
        {
            "tempComponentId": "102",
            "componentId": "1630395483312754688",
            "endDate0": "2023-03-11 10:09:15",
            "startDate2": "2023-03-11 15:00:00",
            "toolPedestalType0": "4号制梁台座",
            "startDate1": "2023-03-11 10:20:17",
            "endDate1": "2023-03-11 14:18:20",
            "endDate2": "2023-03-11 19:00:00"
        }
    ],
    "code": 200,
    "msg": "查询成功"
}

表格内容data为一个对象,自动定位到rows,可自行修改

字段名一一对应,就可以了

效果如图

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

口天三告然

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

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

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

打赏作者

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

抵扣说明:

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

余额充值