写在前面: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';
})
})
}
}