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 相关文章推荐
ArrayList类(增强版)
Apr 04 Javascript
JS操作CSS随机改变网页背景实现思路
Mar 10 Javascript
Javascript数据结构与算法之列表详解
Mar 12 Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 Javascript
Google 地图获取API Key详细教程
Aug 06 Javascript
原生JS实现匀速图片轮播动画
Oct 18 Javascript
关于Iframe父页面与子页面之间的相互调用
Nov 22 Javascript
BootStrapTable服务器分页实例解析
Dec 20 Javascript
jQuery插件FusionCharts实现的3D柱状图效果实例【附demo源码下载】
Mar 03 Javascript
JavaScript 中Date对象的格式化代码方法汇总
Sep 06 Javascript
javascript trie前缀树的示例
Jan 29 Javascript
小程序自定义圆形进度条
Nov 17 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
不用GD库生成当前时间的PNG格式图象的程序
2006/10/09 PHP
php的memcached客户端memcached
2011/06/14 PHP
PHP安全的URL字符串base64编码和解码
2014/06/19 PHP
destoon二次开发常用数据库操作
2014/06/21 PHP
php抽象类使用要点与注意事项分析
2015/02/09 PHP
php计算给定日期所在周的开始日期和结束日期示例
2017/02/06 PHP
IE和firefox浏览器的event事件兼容性汇总
2009/12/06 Javascript
input的focus方法使用
2010/03/13 Javascript
使用非html5实现js板连连看游戏示例代码
2013/09/22 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
2014/09/06 Javascript
javascript实现表单提交后,提交按钮不可用的方法
2015/04/18 Javascript
js动态生成form 并用ajax方式提交的实现方法
2016/09/09 Javascript
jQuery动态创建元素以及追加节点的实现方法
2016/10/20 Javascript
基于js实现二级下拉联动
2016/12/17 Javascript
使用vue.js实现联动效果的示例代码
2017/01/10 Javascript
JavaScript如何对图片进行黑白化
2018/04/10 Javascript
jQuery创建及操作xml格式数据示例
2018/05/26 jQuery
NodeJS有难度的面试题(能答对几个)
2019/10/09 NodeJs
微信小程序页面渲染实现方法
2019/11/06 Javascript
Vue-cli assets SubDirectory及PublicPath区别详解
2020/08/18 Javascript
JavaScript中CreateTextFile函数
2020/08/30 Javascript
Python中字符串对齐方法介绍
2015/05/21 Python
python json.loads兼容单引号数据的方法
2018/12/19 Python
处理textarea中的换行和空格
2019/12/12 HTML / CSS
Ralph Lauren法国官网:美国高品味时装品牌
2017/12/08 全球购物
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物
如何强制垃圾回收
2015/10/06 面试题
企划主管岗位职责
2013/12/12 职场文书
网上开店必备创业计划书
2014/01/26 职场文书
企业内控岗位的职责
2014/02/07 职场文书
12.4法制宣传日活动总结
2014/08/26 职场文书
公司领导班子召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
2015中学学校工作总结
2015/07/20 职场文书
煤矿安全生产管理协议书
2016/03/22 职场文书
Redis之RedisTemplate配置方式(序列和反序列化)
2022/03/13 Redis
JS实现简单的九宫格抽奖
2022/06/28 Javascript