按照官网描述,标签超过swipe-threshold的值(默认5)的时候,会把当前选中标签居中
项目中使用van-tabs组件时发现有以下问题,当前选中的标签并没有居中,并且横向滚动的位置也很奇怪。
查看van-tabs源码:
// vant/lib/tabs/index.js
watch: {
...
currentIndex: function currentIndex() {
this.scrollIntoView();
this.setLine(); // scroll to correct position
if (this.stickyFixed && !this.scrollspy) {
(0, _scroll.setRootScrollTop)(Math.ceil((0, _scroll.getElementTop)(this.$el) - this.offsetTopPx));
}
},
...
},
methods: {
// scroll active tab into view
scrollIntoView: function scrollIntoView(immediate) {
var titles = this.$refs.titles;
if (!this.scrollable || !titles || !titles[this.currentIndex]) {
return;
}
var nav = this.$refs.nav;
var title = titles[this.currentIndex].$el;
var to = title.offsetLeft - (nav.offsetWidth - title.offsetWidth) / 2;
(0, _utils2.scrollLeftTo)(nav, to, immediate ? 0 : +this.duration);
},
}
// ./utils2
function scrollLeftTo(scroller, to, duration) {
var count = 0;
var from = scroller.scrollLeft;
var frames = duration === 0 ? 1 : Math.round(duration * 1000 / 16);
function animate() {
scroller.scrollLeft += (to - from) / frames;
// 主要是这里滚动的值有问题,但原因暂未搞清楚
if (++count < frames) {
(0, _raf.raf)(animate);
}
}
animate();
}
处理方案:虽然还没搞清楚是什么原因导致的bug,但是可以定位到具体哪几行代码的问题,最直接的打补丁重写scrollLeftTo方法即可
// 创建src/patches/van-tabs.js
import { Tabs } from 'vant'
const TabsPatched = {
extends: Tabs,
methods: {
// scroll active tab into view
scrollIntoView: function scrollIntoView(immediate) {
var titles = this.$refs.titles;
if (!this.scrollable || !titles || !titles[this.currentIndex]) {
return;
}
var nav = this.$refs.nav;
var title = titles[this.currentIndex].$el;
var to = title.offsetLeft - (nav.offsetWidth - title.offsetWidth) / 2;
// 注释原来的scrollLeftTo方法,直接设置容器的scrollLeft将当前选中的标签滚动至居中位置
// (0, _utils2.scrollLeftTo)(nav, to, immediate ? 0 : +this.duration);
setTimeout(_ => {
nav.scrollLeft += to - nav.scrollLeft
}, immediate ? 0 : this.duration * 1000)
},
}
}
export default {
install(Vue) {
Vue.component(Tabs.name, TabsPatched)
}
}
// 在main.js引入替换原来的tabs组件
import Vue from 'vue'
import TabsPatched from '@/patches/van-tabs'
Vue.use(TabsPatched)
补丁修复后: