element-ui 封装table组件(自动填满父容器高度,固定头部滚动)

写在前面:element-ui的表格组件是常用的组件之一,唯一不太好的是,当页面组件高度由百分比算出来的时候想让头部固定滚动需要另写JavaScript计算,所以将计算封装在了组件里面(el-table-plus),只映射了部分常用的属性,如果需要可以自行映射其他属性

<!-- el-table-plus -->
<template>
  <div style="height: 100%">
    <el-table
      ref="table"
      :data="data"
      :size="size"
      v-loading="loading"
      element-loading-text="拼命加载中"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
      :height="tableHeight"
      :row-style="rowStyle"
      :row-key="rowKey"
      :stripe="stripe"
      :border="border"
      @cell-mouse-enter="(row, column, cell, event) => $emit('cell-mouse-enter', row, column, cell, event)"
      @cell-mouse-leave="(row, column, cell, event) => $emit('cell-mouse-leave', row, column, cell, event)"
      @expand-change="(row, expandedRows)=>$emit('expand-change', row, expandedRows)"
      @row-dblclick="(row, column, event) => $emit('row-dbclick', row, column, event)"
      @row-contextmenu="(row, column, event) => $emit('row-contextmenu', row, column, event)"
      style="width: 100%">
      <slot/>
    </el-table>
  </div>
</template>

<script>
/*<!--属性没有全部映射,需要的自行添加到prop,禁止添加其他的必须属性,否则会引起已引用组件页面报错-->*/
export default {
  name: "el-table-plus",
  props: {
    data: {
      type: Array,
      // eslint-disable-next-line vue/require-valid-default-prop
      default: () => [],
    },
    size: {
      type: String,
      default: () => 'mini'
    },
    loading: {
      type: Boolean,
      default: () => false,
    },
    rowStyle: {
      type: Function || Object,
      required: false,
    },
    rowKey: {
      type: Function || Object,
      required: false,
    },
    stripe: {
      type: Boolean,
      required: false,
      default: () => true
    },
    border: {
      type: Boolean,
      required: false,
      default: () => false,
    }
  },
  data() {
    return {
      tableHeight: 800,
    }
  },
  methods: {
    toggleRowExpansion(row, expanded) {
      this.$refs.table.toggleRowExpansion(row, expanded);
    },
    calcTableHeight() {
      this.$nextTick(() => {
        if (this.$refs.table) {
          this.tableHeight = this.$refs.table.$el.parentElement.offsetHeight;
        }
      })
    }
  },
  updated() {
    this.$nextTick(() => {
      this.$refs.table.doLayout();
    });
    this.calcTableHeight();
  },
  mounted() {
    this.calcTableHeight();
  },
  created() {
  },
}
</script>

<style scoped>

</style>

使用:

<el-table-plus :data="tableData">
<!-- 在这里正常写el-table下的组件就行 -->
<el-table-column>

</el-table-column>
</el-table-plus>

更新TSX版的: ElTablePlus.tsx

import {Component, Prop, Vue} from 'vue-property-decorator'

@Component({})
export default class ElTablePlus extends Vue {
  // data
  public tableHeight?: string = '500px';


  // props
  @Prop({required: true}) public data!: [];
  @Prop() public size!: string;
  @Prop() public loading!: boolean;
  @Prop() public elementLoadingText!: string;
  @Prop() public elementLoadingSpinner!: string;
  @Prop() public elementLoadingBackground?: string;
  @Prop() public rowStyle?: string | object;
  @Prop() public rowKey?: string;
  @Prop() public stripe?: boolean;
  @Prop() public border?: boolean;


  render() {
    return (
      <el-table
        on={{
          ['cell-mouse-enter']: (row: any, column: any, cell: any, event: Event) =>
            this.$emit('cell-mouse-enter', row, column, cell, event),
          ['cell-mouse-leave']: () => (row: any, column: any, cell: any, event: Event) =>
            this.$emit('cell-mouse-leave', row, column, cell, event),
          ['expand-change']: () => (row: any, expandedRows: any) =>
            this.$emit('expand-change', row, expandedRows),
          ['row-dblclick']: () => (row: any, column: any, event: Event) =>
            this.$emit('row-dblclick', row, column, event),
          ['row-contextmenu']: () => (row: any, column: any, event: Event) =>
            this.$emit('row-contextmenu', row, column, event),
        }}
        style={{'width': '100%'}}
        data={this.data}
        vLoading={this.loading}
        element-loading-text={this.elementLoadingText}
        element-loading-spinner={this.elementLoadingSpinner}
        element-loading-background={this.elementLoadingBackground}
        row-style={this.rowStyle}
        row-key={this.rowKey}
        stripe={this.stripe}
        border={this.border}
        height={this.tableHeight}
      >
        {this.$scopedSlots.default}
      </el-table>
    )
  }

  mounted() {
    this.$nextTick(() => {
      this.tableHeight = this.$parent.$el.clientHeight + 'px';
    })
    window.addEventListener('resize', () => {
      this.$nextTick(() => {
        this.tableHeight = this.$parent.$el.clientHeight + 'px';
      })
    })
  }

}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值