这个标签栏,属于一个很常见的组件,一般我不用这个组件,自己手写一个scroll-view以及样式,更加轻便。但是我写的最简单的标签页没有滚动效果,以及选中标签动画效果。因此根据标签栏滚动学习下,并且自己手写一个标签栏。
这些是所涉及到的文件以及代码
这是滚动需要的页面元素和样式
其中可以出现点击滚动效果的是因为有scroll-x,scroll-with-animation,scroll-left这个三个属性。
然后通过点击标签进行调用计算scroll-left的方法,这样就可以进行滚动。
<scroll-view scroll-x="{{ scrollable }}" scroll-with-animation="{{ scrollWithAnimation }}" scroll-left="{{ scrollLeft }}" class="{{ utils.bem('tabs__scroll', [type]) }}" style="{{ color ? 'border-color: ' + color : '' }}">
<view class="{{ utils.bem('tabs__nav', [type, { complete: !ellipsis }]) }} nav-class" style="{{ computed.navStyle(color, type) }}">
<view wx:if="{{ type === 'line' }}" class="van-tabs__line" style="{{ computed.lineStyle({ color, lineOffsetLeft, lineHeight, skipTransition, duration, lineWidth, inited }) }}" />
<view wx:for="{{ tabs }}" wx:key="index" data-index="{{ index }}" class="{{ computed.tabClass(index === currentIndex, ellipsis) }} {{ utils.bem('tab', { active: index === currentIndex, disabled: item.disabled, complete: !ellipsis }) }}" style="{{ computed.tabStyle({ active: index === currentIndex, ellipsis, color, type, disabled: item.disabled, titleActiveColor, titleInactiveColor, swipeThreshold, scrollable }) }}" bind:tap="onTap">
<view class="{{ ellipsis ? 'van-ellipsis' : '' }}" style="{{ item.titleStyle }}">
{{ item.title }}
<van-info wx:if="{{ item.info !== null || item.dot }}" info="{{ item.info }}" dot="{{ item.dot }}" custom-class="van-tab__title__info" />
</view>
</view>
</view>
</scroll-view>
这个方法是计算scrollLeft 距离的方法,选出元素(van-tabs__nav黄色框和van-tab每个红色框)得到宽度,并且计算距离scrollLeft的位置。
getAllRect和getRect是用来选择节点的封装方法
scrollIntoView() {
const { currentIndex, scrollable, scrollWithAnimation } = this.data;
if (!scrollable) {
return;
}
Promise.all([
getAllRect(this, '.van-tab'),
getRect(this, '.van-tabs__nav'),
]).then(([tabRects, navRect]) => {
console.log("tabRects",tabRects)
console.log("tabRects",navRect)
const tabRect = tabRects[currentIndex];
const offsetLeft = tabRects
.slice(0, currentIndex)
.reduce((prev, curr) => prev + curr.width, 0);
this.setData({
scrollLeft: offsetLeft - (navRect.width - tabRect.width) / 2,
});
if (!scrollWithAnimation) {
nextTick(() => {
this.setData({ scrollWithAnimation: true });
});
}
});
},
根据Tab标签页的源码,页面元素进行修改,js不变,依然使用scrollIntoView方法。在进行tab切换的时候调用scrollIntoView方法。
下划线滑动动画
这个是涉及到的下划线的页面元素和样式
这是动态滑动样式的方法,其中定义了移动的距离,背景颜色,高度,移动速度。
计算lineOffsetLeft的方法,和上面的计算方法同理