uniapp实现可滑动选项卡


Posted in Javascript onOctober 21, 2020

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

tabControl-tag.vue

<template name="tabControl">
 <scroll-view scroll-x="true" :style="'background-color:'+bgc+';top:'+top+'px;'" :class="fixed?'fxied':''" :scroll-left='scrollLeft' scroll-with-animation id="tabcard">
 <view class="tabList" :style="isEqually?'display: flex;justify-content: space-between;padding-left:0;':''">
 <view
  :class="'tabItem'+(currentIndex==index?' thisOpenSelect':'')"
  :style="isEqually? 'width:'+windowWidth/values.length+'px;margin-right:0;':''"
  v-for="(item,index) in values" 
  :id="'item'+index"
  :key='index' 
  @click="_onClick(index)">
  <text :style="(currentIndex==index?'font-size:'+activeSize+'rpx;color:'+activeColor:'font-size:'+itemSize+'rpx')">{{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% 才可以全屏滑动切换

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

Javascript 相关文章推荐
CSS+Table图文混排中实现文本自适应图片宽度(超简单+跨所有浏览器)
Feb 14 Javascript
javascript 多级checkbox选择效果
Aug 20 Javascript
js表头排序实现方法
Jan 16 Javascript
JavaScript返回上一页的三种方法及区别介绍
Jul 04 Javascript
实例讲解JS中setTimeout()的用法
Jan 28 Javascript
jQuery绑定事件-多种实现方式总结
May 09 Javascript
基于d3.js实现实时刷新的折线图
Aug 03 Javascript
聊一聊Vue.js过渡效果
Sep 07 Javascript
jQuery读取本地的json文件(实例讲解)
Oct 31 jQuery
Vue 换肤的示例实践
Jan 23 Javascript
Vue源码解读之Component组件注册的实现
Aug 24 Javascript
JS实现头条新闻的经典轮播图效果示例
Jan 30 Javascript
element中table高度自适应的实现
Oct 21 #Javascript
vue+springboot+element+vue-resource实现文件上传教程
Oct 21 #Javascript
原生小程序封装跑马灯效果
Oct 21 #Javascript
uniapp实现横向滚动选择日期
Oct 21 #Javascript
实现vuex原理的示例
Oct 21 #Javascript
详解JavaScript类型判断的四种方法
Oct 21 #Javascript
node.js如何根据URL返回指定的图片详解
Oct 21 #Javascript
You might like
Laravel 5框架学习之日期,Mutator 和 Scope
2015/04/08 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
详解PHP处理密码的几种方式
2016/11/30 PHP
浅谈PHP匿名函数和闭包
2019/03/08 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
2019/03/12 PHP
Nigma vs AM BO3 第二场2.13
2021/03/10 DOTA
jquery实现的超出屏幕时把固定层变为定位层的代码
2010/02/23 Javascript
jquery二级导航内容均分的原理及实现
2013/08/13 Javascript
Js保留小数点的4种效果实现代码分享
2014/04/12 Javascript
JQuery中$.each 和$(selector).each()的区别详解
2015/03/13 Javascript
jquery validate表单验证的基本用法入门
2016/01/18 Javascript
jQuery ajaxForm()的应用
2016/10/14 Javascript
JavaScript 最佳实践:帮你提升代码质量
2016/12/03 Javascript
vue实现ajax滚动下拉加载,同时具有loading效果(推荐)
2017/01/11 Javascript
jQuery操作DOM_动力节点Java学院整理
2017/07/04 jQuery
使用vue构建移动应用实战代码
2017/08/02 Javascript
浅谈react+es6+webpack的基础配置
2017/08/09 Javascript
jQuery实现列表的增加和删除功能
2018/06/14 jQuery
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
JS实现li标签的删除
2019/04/12 Javascript
微信小程序云开发使用方法新手初体验
2019/05/16 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
讲解Python中fileno()方法的使用
2015/05/24 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
一行Python代码过滤标点符号等特殊字符
2019/08/12 Python
Python 通过正则表达式快速获取电影的下载地址
2020/08/17 Python
草莓网美国官网:Strawberrynet USA
2016/12/11 全球购物
工程预算与管理应届生求职信
2013/10/06 职场文书
会计专业导师推荐信
2014/03/08 职场文书
幼儿园保育员责任书
2014/07/22 职场文书
建设办主任四风问题整改思路和措施
2014/09/20 职场文书
辞职信怎么写
2015/02/27 职场文书
Python实现视频中添加音频工具详解
2021/12/06 Python
python flappy bird小游戏分步实现流程
2022/02/15 Python
彻底弄懂Python中的回调函数(callback)
2022/06/25 Python