问题原因:elementUI table组件的开发者对固定列的宽度计算只计算到了第一层,所以当第一层的宽度小于其子级总宽度的时候就会导致内容被遮挡。(也不知道是不是table组件的开发者是不是故意为之...)
解决方案,重写updateColumnsWidth方法,基于原型替换默认的updateColumnsWidth方法;
实现代码:
import Vue from 'vue';
// 重写fxied固定逻辑,解决定宽内容遮挡
export default function updateColumnsWidth(){
if (Vue.prototype.$isServer) return;
const fit = this.fit;
const bodyWidth = this.table.$el.clientWidth;
let bodyMinWidth = 0;
const flattenColumns = this.getFlattenColumns();
let flexColumns = flattenColumns.filter((column) => typeof column.width !== 'number');
flattenColumns.forEach((column) => {
if (typeof column.width === 'number' && column.realWidth) column.realWidth = null;
});
if (flexColumns.length > 0 && fit) {
flattenColumns.forEach((column) => {
bodyMinWidth += column.width || column.minWidth || 80;
});
const scrollYWidth = this.scrollY ? this.gutterWidth : 0;
if (bodyMinWidth <= bodyWidth - scrollYWidth) { // 不需要导航条
this.scrollX = false;
const totalFlexWidth = bodyWidth - scrollYWidth - bodyMinWidth;
if (flexColumns.length === 1) {
flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth;
} else {
const allColumnsWidth = flexColumns.reduce((prev, column) => prev + (column.minWidth || 80), 0);
const flexWidthPerPixel = totalFlexWidth / allColumnsWidth;
let noneFirstWidth = 0;
flexColumns.forEach((column, index) => {
if (index === 0) return;
const flexWidth = Math.floor((column.minWidth || 80) * flexWidthPerPixel);
noneFirstWidth += flexWidth;
column.realWidth = (column.minWidth || 80) + flexWidth;
});
flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth - noneFirstWidth;
}
} else { // 需要导航条
this.scrollX = true;
flexColumns.forEach(function(column) {
column.realWidth = column.minWidth;
});
}
this.bodyWidth = Math.max(bodyMinWidth, bodyWidth);
this.table.resizeState.width = this.bodyWidth;
} else {
flattenColumns.forEach((column) => {
if (!column.width && !column.minWidth) {
column.realWidth = 80;
} else {
column.realWidth = column.width || column.minWidth;
}
bodyMinWidth += column.realWidth;
});
this.scrollX = bodyMinWidth > bodyWidth;
this.bodyWidth = bodyMinWidth;
}
const fixedColumns = this.store.states.fixedColumns;
if (fixedColumns.length > 0) {
this.fixedWidth = fixedWidthSun(fixedColumns)
}
const rightFixedColumns = this.store.states.rightFixedColumns;
if (rightFixedColumns.length > 0) {
let rightFixedWidth = 0;
rightFixedColumns.forEach(function(column) {
rightFixedWidth += column.realWidth || column.width;
});
this.rightFixedWidth = rightFixedWidth;
}
this.notifyObservers('columns');
}
// 计算固定列宽度
function fixedWidthSun(fixedColumns){
let fixedWidth = 0;
fixedColumns.forEach(function(column) {
fixedWidth += column.children?fixedWidthSun(column.children):column.realWidth || column.width;
});
return fixedWidth
}
下篇:重写elementUi table,实现顶部固定合计行。