uniapp实现可滑动选项卡

(编辑:jimmy 日期: 2024/12/23 浏览:2)

本文实例为大家分享了uniapp实现可滑动选项卡的具体代码,供大家参考,具体内容如下

tabControl-tag.vue

<template name="tabControl">
 <scroll-view scroll-x="true" :style="'background-color:'+bgc+';top:'+top+'px;'" :class="fixed" :scroll-left='scrollLeft' scroll-with-animation id="tabcard">
 <view class="tabList" :style="isEqually">
 <view
  :class="'tabItem'+(currentIndex==index"
  :style="isEqually"
  v-for="(item,index) in values" 
  :id="'item'+index"
  :key='index' 
  @click="_onClick(index)">
  <text :style="(currentIndex==index">{{item}}</text>
  <view class="activeLine" :style="{width: lineWidth+'rpx'}"></view>
 </view>
 </view>
 </scroll-view>
</template>

<script>
 export default {
 name:'tabControl',
 props:{
 current: {
 type: Number,
 default: 0
 },
 values: {
 type: Array,
 default () {
  return []
 }
 },
 bgc:{
 type:String,
 default:''
 },
 fixed:{
 type:Boolean,
 default:false
 },
 scrollFlag:{
 type:Boolean,
 default:false
 },
 lineWidth:{
 type:Number,
 default: 100
 },
 itemSize:{
 type:Number,
 default: 30
 },
 activeSize:{
 type:Number,
 default: 32
 },
 activeColor:{
 type:String,
 default:''
 },
 top:{
 type:Number,
 default: 0
 },
 isEqually:{
 type:Boolean,
 default:false
 }
 },
 data() {
 return {
 currentIndex: 0,
 windowWidth:0, //设备宽度
 leftList:[], //选项距离左边的距离
 widthList:[], //选项宽度
 scrollLeft:0, //移动距离
 newScroll:0, //上一次移动距离(用来判断是左滑还是右滑)
 wornScroll:0, //上一次移动距离(用来判断是左滑还是右滑)
 };
 },
 created(){
 
 },
 mounted(){
 setTimeout(()=>{
 uni.createSelectorQuery().in(this).select("#tabcard").boundingClientRect((res)=>{
  this.$emit('getTabCardHeight', {height:res.height})
 }).exec()
 uni.getSystemInfo({
  success: (res)=> {
  this.windowWidth = res.windowWidth;
   // console.log(this.windowWidth);
  this.values.forEach((i,v)=>{
  let info = uni.createSelectorQuery().in(this);
  info.select("#item"+v).boundingClientRect((res)=>{
  // 获取第一个元素到左边的距离
  // if(v==0){
  // this.startLenght = res.left
  // }
   this.widthList.push(res.width)
  this.leftList.push(res.left)
  
  }).exec()
  
  })
  // console.log(this.leftList)
  // console.log(this.widthList)
  }
 });
 })
 },
 created() {
 this.currentIndex = this.current
 if(this.scrollFlag){
 setTimeout(()=>{
  this.tabListScroll(this.current)
 },300)
 }
 },
 watch: {
 current(val) {
 if (val !== this.currentIndex) {
  this.currentIndex = val
  if(this.scrollFlag){
  this.tabListScroll(val)
  }
 }
 },
 
 },
 methods: {
 _onClick(index) {
 if (this.currentIndex !== index) {
  this.currentIndex = index
  this.$emit('clickItem', {currentIndex:index})
  // 开启滚动
  if(this.scrollFlag){
  this.tabListScroll(index)
  }
 }
 },
 // 选项移动
 tabListScroll(index){
 let scoll = 0;
 this.wornScroll = index;
 // this.wornScroll-this.newScroll>0 在向左滑 ←←←←←
 if(this.wornScroll-this.newScroll>0){
  for(let i = 0;i<this.leftList.length;i++){
  if(i>1&&i==this.currentIndex){
  scoll = this.leftList[i-1]
  }
  }
  // console.log('在向左滑',scoll)
 }else{
  if(index>1){
  for(let i = 0;i<this.leftList.length;i++){
  if(i<index-1){
  scoll = this.leftList[i]
  }
  }
  }else{
  scoll = 0
  }
  // console.log('在向右滑')
 }
 this.newScroll = this.wornScroll;
 this.scrollLeft = scoll;
 }
 }
 }
</script>

<style lang="less" scoped>
 .fxied{
 position: fixed;
 z-index: 2;
 }
 .tabList{
 padding-top: 24rpx;
 padding-left: 24rpx;
 padding-bottom: 8rpx;
 white-space: nowrap;
 text-align: center;
 .tabItem{
 margin-right: 60rpx;
 display: inline-block;
 position: relative;
 text{
 // font-size: 30rpx;
 line-height: 44rpx;
 color: #666;
 transition: all 0.3s ease 0s;
 }
 .activeLine{
 // width: 48rpx;
 height: 8rpx;
 border-radius: 4rpx;
 background-color: #F57341;
 margin-top: 8rpx;
 margin-left: 50%;
 transform: translateX(-50%);
 opacity: 0;
 transition: all 0.3s ease 0s;
 }
 }
 .tabItem:first-child{
 // margin-left: 22rpx;
 }
 .tabItem:last-child{
 margin-right: 24rpx;
 }
 .thisOpenSelect{
 text{
 color: #333;
 font-weight:600;
 // font-size: 32rpx;
 }
 .activeLine{
 opacity: 1;
 }
 }
 }
 
</style>

页面引用

<template>
 <view class="page">
 <tabControl :current="current" :values="items" bgc="#fff" :fixed="true" :scrollFlag="true" :isEqually="false" @clickItem="onClickItem"></tabControl>
 <!-- 使用 swiper 配合 滑动切换 -->
 <swiper class="swiper" style="height: 100%;" @change="scollSwiper" :current="current">
 <swiper-item v-for="(item, index) in items" :key="index">
 <!-- 使用 scroll-view 来滚动内容区域 -->
 <scroll-view scroll-y="true" style="height: 100%;">{{ item }}</scroll-view>
 </swiper-item>
 </swiper>
 </view>
</template>

<script>
import tabControl from '@/components/tabControl-tag/tabControl-tag.vue';
export default {
 components: { tabControl },
 data() {
 return {
 items: ['业绩统计', '选项卡2', '选项卡3', '选项卡4', '选项卡5'],
 current: 0
 };
 },
 onLoad() {},
 methods: {
 onClickItem(val) {
 this.current = val.currentIndex;
 },
 scollSwiper(e) {
 this.current = e.target.current;
 }
 }
};
</script>

<style>
page {
 height: 100%;
}
.page {
 padding-top: 98rpx;
 height: 100%;
}
</style>

1.使用方式:

scrollFlag --是否开启选项滚动(true -开启 false -关闭) 根据自己需求如果选项长度超出屏幕长度 建议开启
fixed --固定定位
bgc --背景色
values --选项数组
current --当前选中选项索引
isEqually --是否开启选项平分宽度(true,false)
lineWidth --下划线长度(在非平分选项状态下 可能会影响选项盒子的宽度-自行调试想要的效果,默认为48rpx)
itemSize --未选中选项字体大小(默认为30rpx)
activeSize --选中选项字体大小(默认为32rpx)
activeColor --选中选项字体颜色(默认#333)
top --选项卡固定定位 自定义top距离

注意:

使用fixed固定头部的时候 要将页面整体padding-top:98rpx;不然会盖住内容区域。
使用swiper实现滑动切换时 要将page 高度设置100% swiper高度100% 才可以全屏滑动切换

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。