前言
这个tabs功能是很多移动端项目都要用的
最近我刚好遇到了这个功能
因为我们项目不让用uview等组件。
所以只能用uniapp自带的组件uni-ui
但是问题就是这里没有这种滚动的tabs标签组件用啊。
所以万不得已之下,我cv工程师只好动动小手写一个组件了。
刚好这里也发出来保存一下,以后在用到可以直接复制了
效果演示
uniapp 手写一个tabs组件,点击标签会滚动到中间
代码
这是组件,创建一个vue文件直接复制放进去
这里核心点一个是用到scroll-view,靠他来滚动
然后组件点击tabs标签的时候会触发方法拿到对应标签的index
利用这个index给标签高亮,以及传给父组件数据
同时把index传给滚动方法内
滚动方法内通过判断屏幕宽度来确定滚动与否
rect就是包含每个标签的左右距离,根据这个距离来控制滚动
<template>
<!-- tabs组件 -->
<view style="width: 100%;">
<scroll-view class="scroll" scroll-x='true' scroll-with-animation :scroll-left='scrollLeft'>
<view v-for="(item,index) in list" :key="index" @click="getColor(item,index)"
class="flex-shrink px-2 py-1 scroll-item"
:style="{color:act==index?'#007bff':'',borderBottom:act==index?'2px solid #007bff':''}">{{item}}</view>
</scroll-view>
</view>
</template>
<script>
export default {
props: {
// 传入的数组,格式:['xxxx','xxx','xxxx']
list: {
type: Array,
default: function() {
return [];
}
}
},
data() {
return {
act: 0, //高亮显示
scrollLeft: 0 //滚动位置
}
},
methods: {
// 切换当前Tab
getColor(item, index) {
this.act = index //点击的高亮
this.$emit('getTabs', item) //点击后传数据给父组件
this.moveTo(index) //滚动到中间
},
// 将点击元素移动到中间
moveTo(index) {
const query = uni.createSelectorQuery().in(this)
query
.selectAll(`.scroll-item`) //拿到每一个tabs标签
.boundingClientRect(rect => {
const {
windowWidth
} = uni.getSystemInfoSync(); //获取屏幕宽度
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">
.scroll {
width: 100%;
white-space: nowrap; //标签不换行
view {
display: inline-block;
font-size: 30upx;
font-weight: 400;
line-height: 42upx;
padding: 18upx 30upx;
color: #000;
position: relative;
&.active {
font-size: 36upx;
font-weight: 800;
line-height: 50upx;
}
&.active::after {
content: '';
display: block;
width: 100%;
border-left: 30upx solid #fff;
border-right: 30upx solid #fff;
box-sizing: border-box;
height: 19upx;
position: absolute;
left: 0;
bottom: 19upx;
background: #FFC385;
z-index: -1;
}
}
}
</style>
使用方法:
看图,主要就是引入组件,然后传入数组,和方法里获取点击的标签