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

实现效果如图

uniapp 左右滑动切换页面并切换tab_第1张图片

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

tab栏部分


				
					{{item.name}}
					
					
				
			

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

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

下方内容部分


			
				
					
						
							
								
								{{item.idea_name}}
							
							
						

					
				
				
					
					空空如也~
				
			
		

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

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

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

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

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

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

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

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

uniapp 左右滑动切换页面并切换tab_第3张图片

 

tabs部分


				
					
				
				
					
				
            

列表部分


				
					
						
							
								
								
								{{item.idea_name}}
								
									
										{{val.tag_name}}
									
								
								{{item.updatetime | getDateDiff}}
							
							
								

								
									
										
										
										{{item.comment_count}}
									
									
										
										{{item.like_count}}
									
								
							
						
					
					
						
						空空如也~
					
				
			

 如代码所以,我使用了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()
				}
			},

 

你可能感兴趣的:(uni-app)