解决方案是继承覆盖element的Table组件,并重写Table组件的bindEvents和syncPostion方法,因为根据源代码发现,Table中的syncPostion方法可能出于性能的原因使用了防抖,我们这里就直接把防抖拿掉了,但这不是产生问题的主要原因,这个只是会导致轻微的迟滞。
产生这个问题的最主要原因是:滚轮事件会自动触发滚动事件,滚动事件中自动使用了behavior: 'smooth’机制,这个机制会让滚动看起来很丝滑,但会耗费更多的性能,估计浏览器处于性能考虑导致两个滚动效果不同步了
所以解决方案就是取消掉滚轮事件的默认行为,我们自己手写滚动
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);
});