前段时间突然发现,当固定table列的时候,右侧的滚动条会被折腾,而不能拖动,上图
以前的时候固定列都是在右侧,也没有注意到这种问题,上次放到左侧,才发现拖不了了,上官方issues上找到了问题所在,官方的bug
支持设置chrome的滚动条,:barHeight='10',:barWidth='10'
方案一通过设置css属性.el-table__body-wrapper{z-index: 2}就可以了,但是有个小问题就是右侧浮动,中间的部分,失去了阴影,感觉没有分离开
方案二
于是乎,根据提供的解决方案,覆盖了本地el-table组件
创建文件夹xTable
-index.vue
-xTable.js
index.vue文件
<!-- 解决table bug,固定fixed滚动条 -->
<!-- 如果出现问题的,可以使用xTable来解决 -->
<template>
<div class="el-table"
:class="[{
'el-table--fit': fit,
'el-table--striped': stripe,
'el-table--border': border || isGroup,
'el-table--hidden': isHidden,
'el-table--group': isGroup,
'el-table--fluid-height': maxHeight,
'el-table--scrollable-x': layout.scrollX,
'el-table--scrollable-y': layout.scrollY,
'el-table--enable-row-hover': !store.states.isComplex,
'el-table--enable-row-transition': (store.states.data || []).length !== 0 && (store.states.data || []).length < 100
}, tableSize ? `el-table--${ tableSize }` : '']"
@mouseleave="handleMouseLeave($event)">
<div class="hidden-columns" ref="hiddenColumns">
<slot></slot>
</div>
<div
v-if="showHeader"
v-mousewheel="handleHeaderFooterMousewheel"
class="el-table__header-wrapper"
ref="headerWrapper">
<table-header
ref="tableHeader"
:store="store"
:border="border"
:default-sort="defaultSort"
:style="{
width: layout.bodyWidth ? layout.bodyWidth + 'px' : ''
}">
</table-header>
</div>
<div
class="el-table__body-wrapper"
ref="bodyWrapper"
:class="[layout.scrollX ? `is-scrolling-${scrollPosition}` : 'is-scrolling-none']"
:style="[bodyHeight,cssVars]">
<table-body
:context="context"
:store="store"
:stripe="stripe"
:row-class-name="rowClassName"
:row-style="rowStyle"
:highlight="highlightCurrentRow"
:style="{
width: bodyWidth
}">
</table-body>
<div
v-if="!data || data.length === 0"
class="el-table__empty-block"
ref="emptyBlock"
:style="emptyBlockStyle">
<span class="el-table__empty-text">
</span>
</div>
<div
v-if="$slots.append"
class="el-table__append-wrapper"
ref="appendWrapper">
<slot name="append"></slot>
</div>
</div>
<div
v-if="!data || data.length === 0"
class="el-table__empty-block"
ref="emptyBlock"
:style="[bodyHeight, {
position:'absolute',
top: layout.headerHeight - (layout.scrollX ? scrollbarHeight : 0) + 'px'
}]">
<span class="el-table__empty-text">
<slot name="empty">{{ emptyText || t('el.table.emptyText') }}</slot>
</span>
</div>
<div
v-if="showSummary"
v-show="data && data.length > 0"
v-mousewheel="handleHeaderFooterMousewheel"
class="el-table__footer-wrapper"
style="margin-top: 0px"
ref="footerWrapper">
<table-footer
:store="store"
:border="border"
:sum-text="sumText || t('el.table.sumText')"
:summary-method="summaryMethod"
:default-sort="defaultSort"
:style="{
width: layout.bodyWidth ? layout.bodyWidth + 'px' : ''
}">
</table-footer>
</div>
<div
v-if="fixedColumns.length > 0"
v-mousewheel="handleFixedMousewheel"
class="el-table__fixed"
ref="fixedWrapper"
:style="[{
width: layout.fixedWidth ? layout.fixedWidth + 'px' : ''
},
fixedHeight]">
<div
v-if="showHeader"
class="el-table__fixed-header-wrapper"
ref="fixedHeaderWrapper">
<table-header
ref="fixedTableHeader"
fixed="left"
:border="border"
:store="store"
:style="{
width: bodyWidth
}"></table-header>
</div>
<div
class="el-table__fixed-body-wrapper"
ref="fixedBodyWrapper"
:style="[{
top: layout.headerHeight + 'px'
},
fixedBodyHeight]">
<table-body
fixed="left"
:store="store"
:stripe="stripe"
:highlight="highlightCurrentRow"
:row-class-name="rowClassName"
:row-style="rowStyle"
:style="{
width: bodyWidth
}">
</table-body>
<div
v-if="$slots.append"
class="el-table__append-gutter"
:style="{ height: layout.appendHeight + 'px'}"></div>
</div>
</div>
<div
v-if="fixedColumns.length > 0 && showSummary"
v-show="data && data.length > 0"
class="el-table__fixed-footer-wrapper"
ref="fixedFooterWrapper"
:style="{
width: layout.fixedWidth ? layout.fixedWidth + 'px' : '',
overflow: 'hidden'
}">
<table-footer
fixed="left"
:border="border"
:sum-text="sumText || t('el.table.sumText')"
:summary-method="summaryMethod"
:store="store"
:style="{
width: bodyWidth,
}"></table-footer>
</div>
<div
v-if="rightFixedColumns.length > 0"
v-mousewheel="handleFixedMousewheel"
class="el-table__fixed-right"
ref="rightFixedWrapper"
:style="[{
width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '',
right: layout.scrollY ? (border ? scrollbarWidth : (scrollbarWidth || 0)) + 'px' : ''
},
fixedHeight]">
<div v-if="showHeader"
class="el-table__fixed-header-wrapper"
ref="rightFixedHeaderWrapper">
<table-header
ref="rightFixedTableHeader"
fixed="right"
:border="border"
:store="store"
:style="{
width: bodyWidth
}"></table-header>
</div>
<div
class="el-table__fixed-body-wrapper"
ref="rightFixedBodyWrapper"
:style="[{
top: layout.headerHeight + 'px'
},
fixedBodyHeight]">
<table-body
fixed="right"
:store="store"
:stripe="stripe"
:row-class-name="rowClassName"
:row-style="rowStyle"
:highlight="highlightCurrentRow"
:style="{
width: bodyWidth
}">
</table-body>
<div
v-if="$slots.append"
class="el-table__append-gutter"
:style="{ height: layout.appendHeight + 'px' }"></div>
</div>
</div>
<div
v-if="rightFixedColumns.length > 0 && showSummary"
v-show="data && data.length > 0"
class="el-table__fixed-right"
ref="fixedFooterWrapper"
:style="{
width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '',left: 'auto',top: 'auto',bottom: '0',
right: layout.scrollY ? (border ? scrollbarWidth : (scrollbarWidth || 0)) + 'px' : 0,
height: layout.footerHeight + 'px',
overflow: 'hidden'
}">
<div
class="el-table__fixed-footer-wrapper"
ref="rightFixedFooterWrapper"
:style="[{
left: 'auto',
right: layout.scrollY ? (border ? scrollbarWidth : (scrollbarWidth || 0)) + 'px' : 0
}]">
<table-footer
fixed="right"
:border="border"
:sum-text="sumText || t('el.table.sumText')"
:summary-method="summaryMethod"
:store="store"
:style="{
width: bodyWidth
}"></table-footer>
</div>
</div>
<div
v-if="rightFixedColumns.length > 0"
class="el-table__fixed-right-patch"
ref="rightFixedPatch"
:style="{
width: layout.scrollY ? scrollbarWidth + 'px' : '0',
height: layout.headerHeight + 'px'
}"></div>
<div class="el-table__column-resize-proxy" ref="resizeProxy" v-show="resizeProxyVisible"></div>
</div>
</template>
<script>
import ELTable from 'element-ui/lib/table'
export default {
extends: ELTable,
name: "XTable",
props: {
barHeight: {
type: Number | String,// 滚动条高度
default: 12
},
barWidth: {
type: Number | String,// 滚动条宽度
default: 11
},
},
data() {
return {
redHeight: 1 // 如果滚动条设置的是谷歌改变的滚动条,那么差值设置为差量值
}
},
watch: {
data(v){
if (v && v.length > 0) {
if (this.fixedColumns.length > 0 && this.showSummary) {
this.$nextTick().then(async () => {
this.layout.updateElsHeight()
await this.$nextTick()
this.layout.updateElsHeight()
})
}
}
}
},
computed: {
scrollbarHeight() {
return this.layout.gutterWidth >= 17 ? this.layout.gutterWidth : this.barHeight
},
scrollbarWidth() {
return this.layout.gutterWidth >= 17 ? this.layout.gutterWidth : this.barWidth
},
cssVars() {
console.log(this.scrollbarHeight)
console.log(this.scrollbarWidth)
return {
"--scrollbarHeight": this.scrollbarHeight + 'px',
"--scrollbarWidth": this.scrollbarWidth + 'px'
};
},
fixedBodyHeight() {
if (this.height) {
return {
height: this.layout.fixedBodyHeight ? this.layout.fixedBodyHeight - (this.scrollbarHeight >= 17 ? 0 : this.scrollbarHeight) + 'px' : ''
};
} else if (this.maxHeight) {
let maxHeight = parseHeight(this.maxHeight);
if (typeof maxHeight === 'number') {
maxHeight = this.layout.scrollX ? maxHeight - this.scrollbarHeight : maxHeight;
if (this.showHeader) {
maxHeight -= this.layout.headerHeight;
}
maxHeight -= this.layout.footerHeight;
return {
'max-height': maxHeight + 'px'
};
}
}
return {};
},
fixedHeight() {
if (this.maxHeight) {
if (this.showSummary) {
return {
height: this.layout.tableHeight ? this.layout.tableHeight - this.layout.footerHeight - (this.layout.scrollX ? this.scrollbarHeight : 0) - this.redHeight + 'px' : ''
}
}
return {
bottom: this.layout.scrollX && this.data.length ? this.scrollbarHeight + 'px' : ''
}
} else {
if (this.showSummary) {
return {
height: this.layout.tableHeight ? this.layout.tableHeight - this.layout.footerHeight - (this.layout.scrollX ? this.scrollbarHeight : 0) - this.redHeight + 'px' : ''
}
}
return {
height: this.layout.scrollX ? 'auto' : this.layout.viewportHeight ? this.layout.viewportHeight + 'px' : '',
bottom: this.layout.scrollX ? this.scrollbarHeight + 'px' : ''
}
}
},
bodyHeight() {
const { headerHeight = 0, bodyHeight, footerHeight = 0} = this.layout;
if (this.height) {
if (this.showSummary) {
return {
height: this.layout.scrollX ? (bodyHeight ? bodyHeight - this.redHeight + 'px' : '') : bodyHeight ? bodyHeight + 'px' : ''
}
}
return {
height: bodyHeight ? bodyHeight + 'px' : ''
};
} else if (this.maxHeight) {
const maxHeight = this.parseHeight(this.maxHeight);
if (typeof maxHeight === 'number') {
return {
'max-height': (maxHeight - footerHeight - (this.showHeader ? headerHeight : 0) - this.redHeight) + 'px'
};
}
}
return {};
},
},
methods: {
parseHeight(height) {
if (typeof height === 'number') {
return height;
}
if (typeof height === 'string') {
if (/^\d+(?:px)?$/.test(height)) {
return parseInt(height, 10);
} else {
return height;
}
}
return null;
}
}
}
</script>
<style scoped lang="scss">
.el-table__fixed-right::before, .el-table__fixed::before{
height: 0!important;
}
.el-table ::v-deep{
.el-table__body-wrapper::-webkit-scrollbar {
height: var(--scrollbarHeight);
width: var(--scrollbarWidth);
}
}
</style>
xTable.js文件
import XTableCom from '@/components/XTable/index'
const XTable = {
install: function(Vue) {
Vue.component('el-table', XTableCom) // 如果不想覆盖el-table的话,那就改成别的名称x-tbale
}
}
export default XTable
在main.js引入组件
import xTable from '@/components/xTable/xTable.js'
// 引入组件
Vue.use(xTable)
原文链接 https://github.com/ElemeFE/element/pull/19716
这样就可以完全覆盖之前的el-table组件了