uniapp 左右滑动切换页面并切换tab

news2025/6/20 20:15:32

实现效果如图

要实现底部内部的左右滑动切换带动上方tab栏的切换,并且下方内容要实现纵向滚动 ,所以需要swiper,swiper-item,scroll-view组合使用

tab栏部分

<view class="tabs">
				<view class="tab_item" v-for="(item,index) in tabList" :key="index" @click="tabSwitch(item,index)">
					<view class="tab_name" :class="activeTab==index?'act_name':''">{{item.name}}</view>
					<view class="tab_cover" v-if="activeTab!=index"></view>
					<image v-else :src="getimg('leaderboard_toggle.png')" style="width: 30rpx;height: 11rpx;"></image>
				</view>
			</view>

 tab栏点击切换,需要重新调取数据

tabSwitch(item, index) {
				this.scrollTop = 0
				this.activeTab = index
				// this.dataList = []
				this.getData()
			},

下方内容部分

<swiper class="data_list" @change="swipeIndex" :current="activeTab"
		 :duration="300" previous-margin="0" :style="{ height: (pageHeight-205)+'px' }" :circular="true">
			<swiper-item v-for="(val,idx) in tabList" :key="idx">
				<scroll-view v-if="dataList.length>0" scroll-y="true" :style="{ height: (pageHeight-205)+'px' }"
					:scroll-top="scrollTop">
					<view style="padding-bottom: 100rpx;">
						<view class="data_item" :class="index*1+1<4?'act_item'+(index*1+1):''"
							v-for="(item,index) in dataList" :key="index" @click="goDetail(item,index)">
							<view class="le">
								<image :src="getimg('Leaderboard_'+(index*1+1)+'.png')" mode="heightFix"
									style="height: 112rpx;"></image>
								<view class="item_content">{{item.idea_name}}</view>
							</view>
							<view class="like_num">{{item.likecount}}</view>
						</view>

					</view>
				</scroll-view>
				<view v-else class="data_none" :style="{ height: (pageHeight-205)+'px' }">
					<image :src="getimg('null-page.png')" style="width: 380rpx;height: 380rpx;"></image>
					<view class="nothing">空空如也~</view>
				</view>
			</swiper-item>
		</swiper>

滑动切换,改变上方tab栏状态,并重新调取数据

swipeIndex(e){
				this.activeTab = e.detail.current
				this.scrollTop = 0
				this.getData()
			}

以上即可实现页面左右滑动切换带动tab栏切换

但是,上面这种方式适合tab栏目比较少,内容列表也比较短的情况,如果tab栏项目很多,内容数据也很多,用swiper做切换会很卡顿,这个官方地址也有介绍swiper | uni-app官网

我懒得去研究怎么去优化他,不过这个博主的优化方式很厉害,可以借鉴一下,附上地址: 

uni-app swiper数量过多时卡顿优化方案_uniapp swiper卡顿_菜鸟驿站2020的博客-CSDN博客 

所以当数据很多时,我使用了touch事件加动画的方式做切换

如图,tab栏选项很多,内容列表数据也很多

 

tabs部分

<view class="tab_box">
				<view style="max-width: 600rpx;height:80rpx ;">
					<u-tabs :list="tabsList" :current="actTab" keyName="category_name" @click="tabSwitch" lineWidth="20"
						lineHeight="4" lineColor="#000000"
						:activeStyle="{color: '#000000',fontWeight: 'bold',transform: 'scale(1.4)'}"
						:inactiveStyle="{color: '#666666',transform: 'scale(1.2)'}"></u-tabs>
				</view>
				<view class="more" @click="cateShow = true">
					<image :src="getimg('originality_label.png')" style="width: 50rpx;height: 50rpx;"></image>
				</view>
            </view>

列表部分

<view class="data_list" @touchstart="touchStart" @touchend="touchEnd" :animation="animationData" 
			:style="{ height: (pageHeight-(marginTop*1+65))+'px' }">
				<scroll-view scroll-y="true" :style="{ height: (pageHeight-(marginTop*1+65))+'px' }"
					@scrolltolower="getBottom" :lower-threshold="80" :scroll-top="scrollTop">
					<view v-if="dataList.length>0" style="padding-bottom: 100rpx;">
						<view class="data_item" v-for="(item,index) in dataList" :key="index"
							@click="goDetail(item,index)">
							<view class="data_top">
								<image :src="getimg('originality_quote.png')" style="width: 64rpx;height: 64rpx;">
								</image>
								<view class="data_content">{{item.idea_name}}</view>
								<view class="lab_box" v-if="item.tag_list && item.tag_list.length>0">
									<view class="lab_item" v-for="(val,idx) in item.tag_list" :key="idx">
										{{val.tag_name}}
									</view>
								</view>
								<view class="times">{{item.updatetime | getDateDiff}}</view>
							</view>
							<view class="data_bot">
								<view class="share" @click.stop="goShare(item,index)">
									<image :src="getimg('share_gray.png')" style="width: 36rpx;height: 36rpx;"></image>
									<view class="share_tt">分享</view>
								</view>

								<view class="infos">
									<view class="comm">
										<image :src="getimg('review_gray.png')" style="width: 44rpx;height: 44rpx;">
										</image>
										<view class="comm_num">{{item.comment_count}}</view>
									</view>
									<view class="comm" @click.stop="addLike(item,index)">
										<image :src="item.is_like?getimg('like_red.png'):getimg('like_gray.png')"
											style="width: 44rpx;height: 44rpx;"></image>
										<view class="comm_num">{{item.like_count}}</view>
									</view>
								</view>
							</view>
						</view>
					</view>
					<view v-else class="data_none" :style="'margin-top:'+(marginTop*1+150)+'px;'">
						<image :src="getimg('null-page.png')" style="width: 380rpx;height: 380rpx;"></image>
						<view class="nothing">空空如也~</view>
					</view>
				</scroll-view>
			</view>

 如代码所以,我使用了touchstart,和touchend事件,并且加了:animation="animationData"

            data(){
                return{
                     scrollTop: 0,
				    startX: 0,
				    startY: 0,
				    animationData: {}, // 动画
                }
               


            }

onLoad中需要先创建动画实例 

onLoad() {
			uni.getSystemInfo({
				success: res => {
					this.pageHeight = res.windowHeight;
				}
			})
			// #ifdef MP-WEIXIN
			const systemInfo = wx.getSystemInfoSync();
			const res = wx.getMenuButtonBoundingClientRect();
			this.height = (res.top - systemInfo.statusBarHeight) * 2 + res.height
			this.marginTop = this.height + systemInfo.statusBarHeight
			// #endif
			
			// 创建动画实例
			this.animation = uni.createAnimation({
				timingFunction: 'ease',
				duration: 120
			})
		},

touchend结束事件中计算手指滑动距离,判断滑动方向并重新调用接口加载数据,并且在判断完滑动方向之后加动效,不让左右滑动看起来生硬

touchStart(event) {
				this.startX = event.touches[0].pageX;
				this.startY = event.touches[0].pageY;
			},
			touchEnd(event) {
				let deltaX = event.changedTouches[0].pageX - this.startX;  
				let deltaY = event.changedTouches[0].pageY - this.startY;
				if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX)>60) {
					if (deltaX < 0) { //往左
						if (this.actTab == this.tabsList.length - 1) {
							this.actTab = 0
						} else {
							this.actTab = this.actTab * 1 + 1
						}
						this.cate_id = this.tabsList[this.actTab].id
						// 动画:左出右进
						this.animation.translateX('-100%').step()
							.opacity(0).step({
								duration: 10
							})
							.translateX('100%').step({
								duration: 10
							})
							.translateX(0).opacity(1).step()
						
						this.animationData = this.animation.export()
						setTimeout(() => {
							this.animationData = {}
						}, 250)
						this.dataList = []
						this.page = 1
						this.getData()
						this.goJust()  //scrollTop改为0
					} else if (deltaX > 0) { //往右
						if (this.actTab == 0) {
							this.actTab = this.tabsList.length - 1
						} else {
							this.actTab = this.actTab * 1 - 1
						}
						this.cate_id = this.tabsList[this.actTab].id
						// 动画:右出左进
						this.animation.translateX('100%').step()  //先横向向右移至100%,即整块移没
							.opacity(0).step({    //再使滑块部分透明
								duration: 10
							})
							.translateX('-100%').step({   //然后趁透明横向向左移至-100%
								duration: 10
							}).translateX(0).opacity(1).step() //接着横向向右移动至初始位置并恢复透明度
						
						this.animationData = this.animation.export()
						// 为避免uniapp动画只有第一次生效,必须延迟删除动画实例数据
						setTimeout(() => {
							this.animationData = {}
						}, 250)
						this.dataList = []
						this.page = 1
						this.getData()
						this.goJust()  //scrollTop改为0
					} else { // 挪动距离0
						
					}
				}else{
					
				}
			},

最后一步,因为内容包裹在scroll-view里,所以触底加载下一页写在scroll-view的触底事件里@scrolltolower="getBottom"

getBottom() {
				if (this.page < this.last_page) {
					this.page += 1
					this.getData()
				}
			},

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/862105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nvidia显卡驱动、CUDA、cuDNN、Anaconda及Tensorflow-GPU版本

Nvidia显卡驱动、CUDA、cuDNN、Anaconda及Tensorflow-GPU版本 一、确定版本关系二、安装过程1.安装显卡驱动2、安装CUDA3、安装cudnn4、安装TensorFlow 三、卸载 一、确定版本关系 1、CUDA与显卡驱动 https://www.nvidia.com/Download/index.aspx 2、cuDNN Toolkit与CUDA版本…

【雕爷学编程】Arduino动手做(12)---霍尔磁场传感器模块4

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

springboot第35集:微服务与flutter安卓App开发

Google Playplay.google.com/apps/publis…[1]应用宝open.qq.com/[2]百度手机助手app.baidu.com/[3]360 手机助手dev.360.cn/[4]vivo 应用商店dev.vivo.com.cn/[5]OPPO 软件商店&#xff08;一加&#xff09;open.oppomobile.com/[6]小米应用商店dev.mi.com/[7]华为应用市场dev…

摆动序列——力扣376

文章目录 题目描述贪心题目描述 贪心 int wiggleMaxLength(vector<int>& nums){int n=nums.

Stable Diffusion基础:ControlNet之人体姿势控制

在AI绘画中精确控制图片是一件比较困难的事情&#xff0c;不过随着 ControlNet 的诞生&#xff0c;这一问题得到了很大的缓解。 今天我就给大家分享一个使用Stable Diffusion WebUI OpenPose ControlNet 复制照片人物姿势的方法&#xff0c;效果可以参考上图。 OpenPose 可以…

将vsCode 打开的多个文件分行(栏)排列,实现全部显示,便于切换文件

目录 1. 前言 2. 设置VsCode 多文件分行(栏)排列显示 1. 前言 主流编程IDE几乎都有排列切换选择所要查看的文件功能&#xff0c;如下为Visual Studio 2022的该功能界面&#xff1a; 图 1 图 2 当在Visual Studio 2022打开很多文件时&#xff0c;可以按照图1、图2所示找到自…

《Linux从练气到飞升》No.11 初识操作系统

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

HTML详解连载(1)

这里写目录标题 HTML定义HTML 超文本标记语言标签语法注意拓展 HTML基本骨架解释VS Code 快速生成骨架&#xff1a;标签的关系父子关系&#xff08;嵌套关系&#xff09;兄弟关系&#xff08;并列关系&#xff09; 代码格式注释 标题标签标签名:h1-h6(双标签)经验&#xff1a; …

十二种排序算法(附动图)

排序算法 一、基本介绍 ​ 排序算法比较基础&#xff0c;但是设计到很多计算机科学的想法&#xff0c;如下&#xff1a; ​ 1、比较和非比较的策略 ​ 2、迭代和递归的实现 ​ 3、分而治之思想 ​ 4、最佳、最差、平均情况时间复杂度分析 ​ 5、随机算法 二、排序算法的分类 …

Linux系统目录结构介绍

Linux系统目录结构介绍 一、目录结构 Linux系统的目录结构是一颗倒状树&#xff1a; “/”表示最顶层的目录&#xff0c;叫做根目录。 &#xff08;1&#xff09;pwd可以显示当前所在的目录。 &#xff08;2&#xff09;cd可以切换当前的目录&#xff0c;例如&#xff0c;…

Jenkins部署python接口自动化测试

一、点击新建Item 二、指定源码和分支 私钥位置&#xff1a;C:\Users\Administrator\.ssh 文件下 三、构建脚本编写 四、构建后操作 指定输出的allure 结果目录

jmeter性能测试常见的一些问题

一、request 请求超时设置 timeout 超时时间是可以手动设置的&#xff0c;新建一个 http 请求&#xff0c;在“高级”设置中找到“超时”设置&#xff0c;设置连接、响应时间为2000ms。 1. 请求连接超时&#xff0c;连不上服务器。 现象&#xff1a; Jmeter表现形式为&#xff…

识别和应对内存抖动

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、案例分析3.1 使用memory-profiler3.2 使用 cp…

ArduPilot飞控之FAILSAFE机制

ArduPilot飞控之FAILSAFE机制 1. 源由2. 设计2.1 遥控信号丢失2.1.1 触发原因2.1.2 场景分析2.1.3 重要参数 2.2 电池低电2.2.1 触发原因2.2.2 场景分析2.2.3 重要参数 2.3 地面站/电传信号丢失2.3.1 触发原因2.3.2 场景分析2.3.3 重要参数 2.4 EKF故障(Extended Kalman Filter…

解密创意保护的钥匙:软著申请流程详解

引言 在当今数字化的浪潮下&#xff0c;软件已经渗透到我们生活的方方面面&#xff0c;从工作到娱乐&#xff0c;从沟通到创新。每一个看似简单的应用程序背后&#xff0c;都蕴藏着无限的创意和智慧。然而&#xff0c;这些创意往往也伴随着被复制、盗用甚至侵权的风险。为了保…

什么是BFC?它有什么作用?如何创建BFC?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是BFC⭐ BFC的作用⭐ 创建BFC的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web…

【100个 Unity实用技能】☀️ | Unity UGUI ScrollView滑动到指定位置

Unity 小科普 老规矩&#xff0c;先介绍一下 Unity 的科普小知识&#xff1a; Unity是 实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者&#xff0c;借助 Unity 将创意变成现实。Unity 平台提供一整套完善的软件解决方案&#xff…

JMeter常用功能及使用方法详解

JMeter被广泛应用于软件性能测试&#xff0c;是一个开源的、纯Java编写的测试工具&#xff0c;其中包括了很多强大的功能。以下将重点介绍JMeter常用功能及使用方法。 一、JMeter压力测试 1.什么是JMeter压力测试&#xff1f; JMeter压力测试就是模拟多种负载条件并分析不同条…

【雕爷学编程】Arduino动手做(07)---电位器模块之电位器调速并带蜂鸣的8位跑马灯

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

详解使用SSH远程连接Ubuntu服务器系统

演示环境&#xff1a; 1.Windows10系统 2.VMware Workstation Pro虚拟机 2.Ubuntu16.04.6&#xff08;以上版本通用&#xff09; 回归正题 一、在Ubuntu端&#xff1a; 1.首先需要安装SSH服务器&#xff0c;在ubuntu终端输入以下指令 sudo apt-get install ssh2.输入你的ubu…