解决方案是继承覆盖element的Table组件,并重写Table组件的bindEvents和syncPostion方法,因为根据源代码发现,Table中的syncPostion方法可能出于性能的原因使用了防抖,我们这里就直接把防抖拿掉了,但这不是产生问题的主要原因,这个只是会导致轻微的迟滞。
产生这个问题的最主要原因是:滚轮事件会自动触发滚动事件,滚动事件中自动使用了behavior: 'smooth’机制,这个机制会让滚动看起来很丝滑,但会耗费更多的性能,估计浏览器处于性能考虑导致两个滚动效果不同步了
所以解决方案就是取消掉滚轮事件的默认行为,我们自己手写滚动
import Vue from 'vue'
import { Table } from 'element-ui';
// 根据阅读Vue源代码(src/core/global-api/extend.js 第23~26),当Vue将一个配置对象注册成组件的时候,会自动的在配置上面
// 加上属性_Ctor,当再次使用同一个配置对象的时候,因为这个对象上面已经有_Ctor[SuperId]了,那么就会直接返回早已经注册后的
// 组件,导致我们下面的注册代码无效果
/* 这就是上述的Vue源代码
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
*/
// 解决方案两个:1.直接让Vue.component...这段注册代码早于Vue.use(ElementUI) 2.执行 delete Table._Ctor后再注册
delete Table._Ctor
Vue.component(
Table.name,
function(resolve){
const bindEvents = Table.methods.bindEvents
Object.assign(Table.methods,{
bindEvents() {
bindEvents.call(this)
this.bodyWrapper.addEventListener('mousewheel', this.handleBodyMousewheel)
},
handleBodyMousewheel(event) {
const fixedWrapper = this.$refs.fixedWrapper
if (fixedWrapper) {
const fixedBodyWrapper = fixedWrapper.querySelector('.el-table__fixed-body-wrapper')
if (fixedBodyWrapper) {
event.preventDefault()
fixedBodyWrapper.scrollBy({ left: event.deltaX, top: event.deltaY })
this.$refs.bodyWrapper.scrollBy({ left: event.deltaX, top: event.deltaY })
}
}
}
})
resolve(Table)
}
)