<template>
<div class="container">
<scroll-view class="scroll" scroll-x='true' scroll-with-animation :scroll-left='scrollLeft'>
<view v-for="(item, index) in tabsList" :key='item.id'
:class="[{ active: currentIndex === index }, 'scroll-item']" @click="changeTab(index)">
{{ item.name }}
</view>
</scroll-view>
</div>
</template>
<script>
export default {
data () {
return {
scrollW: 0,
tabsList: [
{
id: 1,
name: 'demo1'
},
{
id: 2,
name: 'demo2'
},
{
id: 3,
name: 'demo3'
},
{
id: 4,
name: 'demo4'
},
{
id: 5,
name: 'demo5'
},
{
id: 6,
name: 'demo6'
},
{
id: 7,
name: 'demo7'
},
{
id: 8,
name: 'demo8'
},
{
id: 9,
name: 'demo9'
},
{
id: 10,
name: 'demo10'
}
],
currentIndex: 0,
scrollLeft: 0
}
},
onLoad () {
// vue3使用的话好像获取不到boundingClientRect
const query = uni.createSelectorQuery().select('.scroll');
query.boundingClientRect(res => {
this.scrollW = res.width;
}).exec()
},
methods: {
changeTab (index) {
this.currentIndex = index;
this.moveTo(index)
},
moveTo (index) {
const query = uni.createSelectorQuery().in(this)
query.selectAll(`.scroll-item`).boundingClientRect(rect => {
const windowWidth = this.scrollW; // 屏幕宽度
let width = 0
// 循环获取计算当前点击的标签项距离左侧的距离
for (let i = 0; i < index; i++) {
width += rect[i].width
}
// 当大于屏幕一半的宽度则滚动,否则就设置位置为0
if (width > windowWidth / 2) {
this.scrollLeft = width + rect[index].width / 2 - windowWidth / 2
} else {
this.scrollLeft = 0
}
}).exec()
},
}
}
</script>
<style lang="scss" scoped>
.scroll {
width: 100%;
white-space: nowrap;
view {
display: inline-block;
font-size: 30rpx;
font-weight: 400;
line-height: 42rpx;
padding: 18rpx 30rpx;
color: #000;
position: relative;
&.active {
font-size: 36rpx;
font-weight: 800;
line-height: 50rpx;
}
&.active::after {
content: '';
display: block;
width: 100%;
border-left: 30rpx solid #fff;
border-right: 30rpx solid #fff;
box-sizing: border-box;
height: 19rpx;
position: absolute;
left: 0;
bottom: 19rpx;
background: #8591ff;
z-index: -1;
}
}
}
</style>
08-07
690
