uniapp 实现左右滑动切换页面

实现效果:
在这里插入图片描述

方案一
方案一切换的是组件页面,适用于各种场景,但比较繁琐,不够简洁,不想看的小伙伴可直接看方案二!!
方案一vue3.0完整代码:

<template>
	<view>
		<view class="status_bar">
			<!-- 状态栏占位 -->
		</view>
		<view class="container">
			<!-- 搜索/导航 -->
			<view class="top">
				<view class="tabTop">
					<uni-icons type="search" size="30" color="#fff" style="padding-left: 30rpx;"></uni-icons>
					<view class="title">
						<text class="follow" @tap="onFollow" :style="clickFollowStyle">关注</text>
						<text class="square" @tap="onSquare" :style="clickSquareStyle">广场</text>
					</view>
				</view>
			</view>
 
			<!-- 广场 -->
			<view class="squareMain" v-if="isSquare===1">
				<!-- 导航栏 -->
				<view class="tabBar">
					<text v-for="(i,index) in tabBarData" :key="index" @tap="onclick(index)"
						:style="i.style">{{i.text}}</text>
				</view>
				<swiper :current="swiperIndex" style="height: calc(100vh - 260rpx);" @change=handelSwiper>
					<!-- 根据条件显示各个组件页面 -->
					<swiper-item>
						<find v-if="![1, 2, 3, 4, 5, 6].includes(swiperIndex)" />
					</swiper-item>
					<swiper-item>
						<city v-if="swiperIndex===1" />
					</swiper-item>
					<swiper-item>
						<walking v-if="swiperIndex===2" />
					</swiper-item>
					<swiper-item>
						<sea v-if="swiperIndex===3" />
					</swiper-item>
					<swiper-item>
						<play v-if="swiperIndex===4" />
					</swiper-item>
					<swiper-item>
						<hotel v-if="swiperIndex===5" />
					</swiper-item>
					<swiper-item>
						<delicious v-if="swiperIndex===6" />
					</swiper-item>
				</swiper>
			</view>
			<!-- 关注 -->
			<view class="followMain" v-else>
				<follow />
			</view>
		</view>
	</view>
</template>
 
<script setup>
	import {
		ref,
		watch,
		onMounted,
	} from "vue";
 
	// 导入页面组件
	import find from "../../pages/community/find.vue"
	import city from "../../pages/community/city.vue"
	import walking from "../../pages/community/walking.vue"
	import sea from "../../pages/community/sea.vue"
	import play from "../../pages/community/play.vue"
	import hotel from "../../pages/community/hotel.vue"
	import delicious from "../../pages/community/delicious.vue"
	import follow from "../../pages/community/follow/follow.vue"
 
	//控制“关注”和“广场”
	const isSquare = ref(1)
	const clickFollowStyle = ref('color: #FFF;');
	const clickSquareStyle = ref('color: #7e9de2;')
	const onFollow = () => {
		isSquare.value = 0;
		clickFollowStyle.value = 'color: #7e9de2;';
		clickSquareStyle.value = 'color: #FFF;';
	}
	const onSquare = () => {
		isSquare.value = 1
		clickSquareStyle.value = 'color: #7e9de2;';
		clickFollowStyle.value = 'color: #FFF;';
	}
 
	const fold = ref("展开")
	
	// 广场导航
	const tabBarData = ref([{
			text: '发现',
			style: 'color:#7e9de2;border-bottom: 2px solid #7e9de2;'
		},
		{
			text: '城市',
			style: 'color: #fff;'
		},
		{
			text: '徒步',
			style: 'color: #fff;'
		},
		{
			text: '看海',
			style: 'color: #fff;'
		},
		{
			text: '玩乐',
			style: 'color: #fff;'
		},
		{
			text: '酒店',
			style: 'color: #fff;'
		},
		{
			text: '美食',
			style: 'color: #fff;'
		},
	])
 
	// 获取当前页面路径信息
	const pages = getCurrentPages()
	const currentPage = pages[pages.length - 1]
	console.log('当前页面路径:', currentPage.route)
 
	// 滑动触发导航
	const swiperIndex = ref()
	const handelSwiper = (e) => {
		console.log(e.detail.current);
		swiperIndex.value = e.detail.current
		// 导航初始样式
		tabBarData.value.forEach((item, i) => {
			item.style = 'color: #fff;';
		});
		// 滑动导航的样式
		tabBarData.value[e.detail.current].style =
			'color:#7e9de2;border-bottom: 2px solid #7e9de2;font - size: large;';
	}
 
	// 点击触发导航
	const tabIndex = ref()
	const onclick = (index) => {
		console.log(index);
		tabIndex.value = index
		swiperIndex.value = tabIndex.value
		// 导航初始样式
		tabBarData.value.forEach((item, i) => {
			item.style = 'color: #fff;';
		});
		// 点击导航后的样式
		tabBarData.value[index].style = 'color: #7e9de2;border-bottom: 2px solid #7e9de2;font - size: large;';
	}
</script>
 
<style scoped lang="scss">
	.status_bar {
		height: var(--status-bar-height);
		width: 100%;
	}
 
	.container {
		.top {
			position: fixed;
			top: var(--status-bar-height);
			margin-bottom: 10px;
 
			.tabTop {
				display: flex;
				width: 100vw;
				font-size: 40rpx;
				display: flex;
				align-items: center;
				margin-top: 10px;
 
				.title {
					flex: 1;
					text-align: center;
					padding: 18rpx 0;
 
					.follow {
						display: inline;
						margin: 0 30rpx 0 -90rpx
					}
				}
			}
		}
 
		.squareMain {
			.tabBar {
				display: flex;
				align-items: center;
				justify-content: space-around;
				margin: 10px 0;
 
				text {
					display: block;
					padding-bottom: 2px;
				}
			}
 
			position: fixed;
			width: 100vw;
			margin-top: 130rpx;
		}
 
		.followMain {
			position: static;
			margin-top: 130rpx;
		}
	}
</style>

方案二
这个方案是我在看其他博主写的文章时借鉴的思想,比较简练,该博主文章链接:
该文章链接http://t.csdnimg.cn/by5F0
方案二vue3.0完整代码:

<template>
	<view class="status_bar">
		<!-- 状态栏占位 -->
	</view>
	<view class="tabs-container">
		<view v-for="(tab, index) in tabList" :key="index" @tap="tabsOn(index)" :class="{ active: tabsId === index }"
			class="tab">{{ tab.title }}</view>
	</view>
	<swiper @change="slideOn" :current="tabsId">
		<swiper-item v-for="(tab, index) in tabList" :key="index">
			<view>{{ tab.title }} content</view>
		</swiper-item>
	</swiper>
</template>
 
<script setup>
	import {
		ref
	} from 'vue';
 
	const tabList = [{
			title: "发现",
			index: "0"
		},
		{
			title: "城市",
			index: "1"
		},
		{
			title: "徒步",
			index: "2"
		},
		{
			title: "看海",
			index: "3"
		},
		{
			title: "玩乐",
			index: "4"
		},
		{
			title: "酒店",
			index: "5"
		},
		{
			title: "美食",
			index: "6"
		}
	];
 
	const tabsId = ref(0);
 
	const slideOn = (e) => {
		tabsId.value = e.detail.current;
	};
 
	const tabsOn = (index) => {
		tabsId.value = index;
	};
</script>
 
<style scoped lang="scss">
	.status_bar {
		height: var(--status-bar-height);
		width: 100%;
	}
 
	.tabs-container {
		display: flex;
		justify-content: space-between;
		padding: 20px;
 
		.tab {
			padding: 10px;
		}
 
		.active {
			color: #7e9de2;
		}
	}
</style>

方案二vue2.0完整代码

<template>
	<view class="">
		<view class="status_bar">
			<!-- 状态栏占位 -->
		</view>
		<view class="tabs-container">
			<view v-for="(tab, index) in tabList" :key="index" @tap="tabsOn(index)"
				:class="{ active: tabsId === index }" class="tab">{{ tab.title }}</view>
		</view>
		<swiper @change="slideOn" :current="tabsId">
			<swiper-item v-for="(tab, index) in contentList" :key="index">
				<view>{{ tab.content }} </view>
			</swiper-item>
		</swiper>
	</view>

</template>

<script>
	export default {
		data() {
			return {
				tabList: [{
						title: "发现",
						index: "0"
					},
					{
						title: "城市",
						index: "1"
					},
					{
						title: "徒步",
						index: "2"
					},
					{
						title: "看海",
						index: "3"
					},
					{
						title: "逛街",
						index: "4"
					},
					{
						title: "酒店",
						index: "5"
					},
					{
						title: "美食",
						index: "6"
					}
				],
				contentList:[
					{
					content:'sdfsdfsdfsdf'
				    },
					{
					content:'sdfsdfsdfsdf'
					},
					{
					content:'sdfsdfsdfsdf'
					},
					{
					content:'sdfsdfsdfsdf'
					},
					{
					content:'sdfsdfsdfsdf'
					},
					{
					content:'sdfsdfsdfsdf'
					},
					{
					content:''
					},
					
				],
				tabsId:0,
			}
		},
		methods:{
			slideOn(e){
				this.tabsId = e.detail.current;
			},
			tabsOn(index){
				this.tabsId = index;
			}
		}
	}

</script>

<style scoped lang="scss">
	.status_bar {
		height: var(--status-bar-height);
		width: 100%;
	}

	.tabs-container {
		display: flex;
		justify-content: space-between;
		padding: 20px;

		.tab {
			padding: 10px;
		}

		.active {
			color: #7e9de2;
		}
	}
</style>

最后效果图

在这里插入图片描述

另外还可以通过scroll-view实现触底加载,以及下拉刷新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒜苔肉丝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值