以前に作成されたコンポーネントであり続け、感謝します
<template>
<div class="FitTable" :style="tableStyle">
<div class="FitTable-header" ref="header" :style="{width:tbodyWidth + 'px', backgroundColor: backgroundColor}">
<div class="FitTable-header__content">
<div v-for="(item, index) in columns" :key="item.unique || index" class="FitTable-cell"
:style="{minWidth: typeof item.minWidth === 'number'?item.minWidth + 'px':item.minWidth,
width: item.width + 'px',
textAlign: item.textAlign || 'center',
height: headerHeight + 'px'}"
:title="item.title">
<slot :name="item.slotHeader" :data="{...item,index}">
<div style="margin: 1px 5px;color: #DBE5E8;">{{item.title}}</div>
</slot>
</div>
</div>
</div>
<div :style="tbodyHeight" ref="tableTbody">
<FitScroll>
<div class="FitTable-body">
<div class="FitTable-body-row">
<div class="FitTable-body-row_line" v-for="(item,index) in data" :key="(dataKey && item[dataKey]) || index" :style="{height: lineHeight}">
<div v-for="(_item, _index) in columns" :key="_item.unique || _index" class="FitTable-cell"
:style="{minWidth: typeof _item.minWidth === 'number'?_item.minWidth + 'px':_item.minWidth,
width: _item.width + 'px',
textAlign: _item.textAlign || 'center'}">
<div class="FitTable-cell-content">
<div class="FitTable-cell-content-data">
<slot :name="_item.slot" :data="{...item,index}">
<span :title="item[_item.key]" style="color: #DBE5E8;">
{{item[_item.key]}}
</span>
</slot>
</div>
</div>
</div>
</div>
</div>
</div>
</FitScroll>
</div>
</div>
</template>
<script>
/* eslint-disable */
export default {
name: "FitTable",
props: {
maxHeight: {
type: String,
default: null
},
// 表格宽度,默认100%
width: {
type: String,
default: '100%'
},
height: {
type: Number | String,
default: '100%'
},
// 起始索引
// startIndex:{
// type: Number,
// default: 0
// },
/* TODO columns接受值: 对象数组
title: 表头名称
slotHeader: 表头插槽名称
slot: 表体插槽
unique: 默认索引值,必须唯一,便于vue优化
key: 对应prop:{data}中数据的键值
minWidth: 对应列最小宽度
*/
columns: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
},
headerHeight: {
type: Number,
default: 35
},
backgroundColor: {
type: String,
// default: '#3c6180',
default: 'rgba(60,97,128,0.3)'
},
lineHeight: {
type: String,
default: ''
},
// prop:{data}中唯一的值,不传则通过索引优化表格
dataKey: {
type: String,
default: null
}
},
computed: {
tableStyle: {
get () {
return {width: this.width,maxHeight: this.maxHeight,height:typeof this.height === 'number' ?this.height + 'px':'100%'};
}
},
tbodyHeight () {
const height = this.tableHeight > (this.maxHeight || Infinity)?this.maxHeight:this.tableHeight;
return { height: height -this.headerHeight + 'px',overflowY: 'auto' };
}
},
watch: {
height () {
if (String(this.height).indexOf('%') !== -1) {
this.tableHeight = this.$el.offsetHeight * parseInt(this.height) / 100
} else {
this.tableHeight = this.height;
}
}
},
data: () => ({
rowWidth: null,
// 将自定义的列width值收集起来的和
customWidth: { count: 0, value: 0 },
tbodyWidth: 0,
tableHeight: 0,
theaderHeight: 0
}),
mounted() {
// const width = this.$el.offsetWidth;
// this.theaderHeight = this.$refs['header'].offsetHeight;
this.$nextTick(() => {
if (String(this.height).indexOf('%') !== -1) {
this.tableHeight = this.$el.offsetHeight * parseInt(this.height) / 100;
} else {
this.tableHeight = this.height;
}
this.tbodyWidth = this.$refs['tableTbody'].clientWidth;
// console.log(this.$el.offsetHeight, this.tableHeight, 777)
});
// this.rowWidth = (width - this.customWidth.value) / (this.columns.length - this.customWidth.count) + 'px';
// // eslint-disable-next-line no-console
window.addEventListener('resize', this.refreshTableRow);
},
beforeDestroy () {
window.removeEventListener('resize', this.refreshTableRow);
},
methods: {
refreshTableRow() {
// if (this.width.indexOf('%') !== -1) {
// const width = this.$el.offsetWidth;
// this.rowWidth = (width - this.customWidth.value) / (this.columns.length - this.customWidth.count) + 'px'
// }
this.theaderHeight = this.$refs['header'].offsetHeight;
if (String(this.height).indexOf('%') !== -1) {
this.tableHeight = this.$el.offsetHeight * parseInt(this.height) / 100
}
this.tbodyWidth = this.$refs['tableTbody'].clientWidth;
}
}
}
</script>
<style lang="scss" scoped>
@import "../../styles/_scroll";
.FitTable {
position: relative;
&-header {
display: table;
table-layout: fixed;
box-sizing: border-box;
// border-bottom: 1px solid rgba(255,255,255,0.32);
&__content {
display: table-header-group;
.FitTable-cell {
display: table-cell;
vertical-align: middle;
> div {
//position: relative;
//top: 50%;
//transform: translateY(-50%);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
}
&-body {
width: 100%;
display: table;
box-sizing: border-box;
table-layout: fixed;
&-row {
display: table-row-group;
&_line {
display: table-row;
&:nth-child(odd) {
background-color: transparent;
}
&:nth-child(even) {
background-color: rgba(158,158,158,0.1);
}
.FitTable-cell {
display: table-cell;
vertical-align: middle;
&-content {
height: 30px;
margin: 1px 5px;
&-data {
position:relative;
top: 15px;
transform: translateY(-50%);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
}
}
}
}
</style>