uniapp 顶部tab + 占满剩余高度的内容区域swiper


javascript 复制代码
<template>
	<view class="page-container">
		<!-- 顶部 Tab 栏 -->
		<view class="tabs-container">
			<scroll-view scroll-x class="tabs-scroll" :show-scrollbar="false">
				<view class="tabs">
					<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: currentTab === index }"
						@click="switchTab(index)">
						{{ tab }}
						<view class="underline" v-if="currentTab === index"></view>
					</view>
				</view>
			</scroll-view>
		</view>

		<!-- 占满剩余高度的 swiper -->
		<swiper class="content-swiper" :current="currentTab" @change="onSwiperChange"
			:style="{ height: swiperHeight + 'px' }">
			<swiper-item v-for="(tab, index) in tabs" :key="index" class="swiper-item">
				<scroll-view scroll-y class="content-scroll" :show-scrollbar="false">
					<!-- 内容区域 -->
					<view class="content-box">
						<text class="title">{{ tab }} 的内容</text>
						<view v-for="item in 20" :key="item" class="demo-item">
							{{ tab }} 的内容项 {{ item }}
						</view>
					</view>
				</scroll-view>
			</swiper-item>
		</swiper>
	</view>
</template>

<script setup lang="ts">
	import { ref, getCurrentInstance } from 'vue'
	import { onLoad, onShow } from '@dcloudio/uni-app'

	const currentTab = ref(0)
	const tabs = ref(['全部', '矿场咨询', '安全教育', '岗位规范'])
	const swiperHeight = ref(500) // 初始高度,后续动态计算

	// 动态计算高度
	const calcSwiperHeight = () => {
		uni.getSystemInfo({
			success: (res) => {
				// 获取屏幕高度
				const screenHeight = res.windowHeight

				// 获取 tabs 容器高度(需要确保 DOM 已渲染)
				// 在 setup 中获取组件实例
				const instance = getCurrentInstance()
				const query = uni.createSelectorQuery().in(instance?.proxy)

				query.select('.tabs-container').boundingClientRect(data => {
					// 计算剩余高度 = 屏幕高度 - tabs 高度 - 安全区域(可选)
					const safeAreaInsets = res.safeAreaInsets?.top || 0
					swiperHeight.value = screenHeight - data.height - safeAreaInsets
				}).exec()
			}
		})
	}

	// 切换 Tab
	const switchTab = (index : number) => {
		currentTab.value = index
	}

	// 滑动 swiper 时同步 Tab
	const onSwiperChange = (e : any) => {
		currentTab.value = e.detail.current
	}

	// 初始化时计算高度
	onLoad(() => {
		calcSwiperHeight()
	})
</script>

<style scoped lang="scss">
	/* 页面容器 */
	.page-container {
		height: 100vh;
		display: flex;
		flex-direction: column;
	}

	/* 顶部 Tab 样式 */
	.tabs-container {
		position: sticky;
		top: 0;
		background: #fff;
		z-index: 999;
		box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
		/* 确保 tabs 容器高度固定 */
		height: 90rpx;
	}

	/* swiper 容器 */
	.content-swiper {
		flex: 1;
		width: 100%;
	}

	/* swiper-item 内部滚动区域 */
	.content-scroll {
		height: 100%;
		padding: 30rpx;
		box-sizing: border-box;
	}

	/* 内容区域样式 */
	.content-box {
		background: #f5f5f5;
		border-radius: 16rpx;
		padding: 30rpx;
	}

	.title {
		font-size: 32rpx;
		font-weight: bold;
		margin-bottom: 30rpx;
		display: block;
	}

	.demo-item {
		padding: 20rpx;
		margin-bottom: 20rpx;
		background: #fff;
		border-radius: 8rpx;
		box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05);
	}

	/* Tab 样式 */
	.tabs-scroll {
		white-space: nowrap;
		width: 100%;
	}

	.tabs {
		display: inline-flex;
		padding: 20rpx 30rpx;
	}

	.tab-item {
		position: relative;
		padding: 20rpx 40rpx;
		font-size: 28rpx;
		color: #666;
		transition: all 0.3s;
	}

	.tab-item.active {
		color: #007AFF;
		font-weight: 500;
	}

	.underline {
		position: absolute;
		bottom: 0;
		left: 50%;
		transform: translateX(-50%);
		width: 60%;
		height: 6rpx;
		background: #007AFF;
		border-radius: 3rpx;
		animation: underlineShow 0.3s ease-out;
	}

	@keyframes underlineShow {
		from {
			width: 0;
			opacity: 0;
		}

		to {
			width: 60%;
			opacity: 1;
		}
	}
</style>
相关推荐
1***s63212 小时前
JavaScript微服务
javascript·微服务·devops
小云朵爱编程12 小时前
Vue项目Iconify的使用以及自定义图标,封装图标选择器
前端·javascript·vue.js
2501_9160074712 小时前
iOS 压力测试的工程化体系,构建高强度、多维度、跨工具协同的真实负载测试流程
android·ios·小程序·uni-app·cocoa·压力测试·iphone
P***253913 小时前
JavaScript部署
开发语言·前端·javascript
一只小阿乐13 小时前
react 状态管理mobx中的行为模式
前端·javascript·react.js·mobx·vue开发·react开发
大雷神13 小时前
DevUI 实战教程:从零构建电商后台管理系统(完整版)
前端·javascript·华为·angular.js
E***q53913 小时前
JavaScript数据挖掘开发
开发语言·javascript·数据挖掘
滿13 小时前
vue3 elementplus el-table toggleRowSelection使用方法
javascript·vue.js·elementui
猪八戒1.014 小时前
onenet接口
开发语言·前端·javascript·嵌入式硬件
h***839314 小时前
JavaScript开源
开发语言·javascript·ecmascript