主要是为了实现 scroll-view 滑动之后的选中项能够水平居中(微信小程序同样适用,需要改几个api)
<template>
<scroll-view class="head__scroll" scroll-x :scroll-left="scrollLeft">
<div class="head__scroll_sport">测试左侧展示内容</div>
<template v-for="(item, index) in options">
<view
class="head__scroll_item"
:class="{ active: active == item.value }"
:key="index"
@click="onSelect(item)"
>
{{ item.label }}
</view>
</template>
</scroll-view>
</template>
<script>
export default {
name: 'Head',
data() {
return {
options: [{label: '测试一', value: 1}, {label: '测试二', value: 2}],
/** 左侧滑动距离 */
scrollLeft: 0,
};
},
methods: {
/** 滚动事件 */
_selectScroll(value) {
const index = this.options.findIndex(
(item) => item.value == value
);
const that = this;
if (index !== -1) {
let halfScreenWidth = 0;
let sportWidth = 0;
const query = uni.createSelectorQuery().in(this);
query
.select('.head__scroll')
.boundingClientRect((data) => {
// scroll-view 整体宽度
halfScreenWidth = data.width / 2;
})
.exec();
query
.select('.head__scroll_sport')
.boundingClientRect((data) => {
// sport name 宽度
sportWidth = data.width;
})
.exec();
query
.selectAll('.head__scroll_item')
.boundingClientRect((rect) => {
/** 当前盒子一半宽度 */
let halfBoxWidth = rect[index].width / 2;
/** 当前选中项前全部box盒子宽度距离和 */
let beforeBoxWidthSum = 0;
/** 循环获取计算当前点击的标签项距离左侧的距离 */
for (let i = 0; i < index; i++) {
beforeBoxWidthSum += rect[i].width;
}
/** 前面所有格子宽度 */
const beforeWidth = sportWidth + halfBoxWidth + beforeBoxWidthSum;
/** 左侧滑动距离 */
that.scrollLeft =
beforeWidth > halfScreenWidth
? beforeWidth - halfScreenWidth + 1 // HACK: essence 1px补偿
: 0;
})
.exec();
}
},
},
};
</script>
<style lang="stylus" scoped>
/* 隐藏滚动条 */
::v-deep ::-webkit-scrollbar
display none
.head__scroll
width 100%
height 26rpx
background #fff
white-space nowrap
.head__scroll_sport,
.head__scroll_item
display inline-block
overflow hidden
box-sizing border-box
padding 0 16rpx
max-width 110rpx
height 100%
color #02173E
text-align center
text-overflow ellipsis
white-space nowrap
font-size 14rpx
&.active
max-width none
border-radius 7.5rpx 7.5rpx 0 0
background #02173D
color #fff
.head__scroll_sport
overflow auto
max-width none
width 80rpx
color #03173C
font-size 16rpx
</style>