uniapp vue3 梯形选项卡组件

实现的效果图:

切换选项卡显示不同的内容,把这个选项卡做成了一个组件,需要的自取。

javascript 复制代码
// 组件名为 trapezoidalTab
<template>  
 <view class="pd24">
	 <view class="nav">
	   <!-- 左侧 -->
	   <view class="item" :class="{ active: activeIndex === 0 }" @click="changeTab(0)"> 
	 		<view :class=" activeIndex === 0 ? 'activeTxt black' : 'itemTxt' ">
	 			{{leftLabel}}
	 		</view>
	   </view>
	 	<!-- 右侧 -->
	 	<view class="item" :class="{ active: activeIndex === 1 }"  @click="changeTab(1)"> 
	 		<view :class="activeIndex == 1 ? 'activeTxt black' : 'itemTxt' ">
	 			{{rightLabel}}
	 		</view>
	 	</view>
	 </view> 
	 
	 <view class="content">
		 <view v-if='activeIndex === 0'>
			 <slot name="left"></slot>
		 </view>
		 <view v-if='activeIndex === 1'>
			  <slot name="right"></slot>
		 </view>
	 </view>
 </view> 
</template>  
  
<script setup> 
	import {
		ref,
		defineProps,
		defineEmits,
	} from 'vue'
	
	const props = defineProps({
		leftLabel: {
		  type: String,
		  default: '到店取'
		},
		rightLabel: {
		  type: String,
		  default: '直达送'
		},
		activeIndex: {
		  type: Number,
		  default: 0
		},
	})
	const emit = defineEmits(['changeTab'])
	const changeTab=(val)=> {
		emit('changeTab',val) 
	}  
</script>  
  
<style lang="scss" scoped>
	.nav{
		display: flex;
		align-items: flex-end;
	}
	.nav .item{
		flex: 1;
		height: 80rpx;
		background: #E6E6E6;
		border-radius: 10rpx 10rpx 0 0;
		position: relative;
		list-style: none;
	}
	.nav .item.active{
		height: 96rpx;
		background: #FFF;
	}
	.nav .item:first-child:before,  
	.nav .item:last-child:before {  
	    content: '';  
	    display: none;  
	    width: 20rpx;  
	    height: 100%;  
	    background: #FFF;  
	    position: absolute;  
	    top: 0;  
	    z-index: 10;  
	}  
	  
	.nav .item:first-child:before {  
	    right: -10rpx;  
	    border-radius: 0 10rpx 0 0;  
	    transform: skew(10deg);  
	}  
	  
	.nav .item:last-child:before {  
	    left: -10rpx;  
	    border-radius: 10rpx 0 0 0;  
	    transform: skew(-10deg);  
	}  
	  
	.nav .item.active:first-child:before,  
	.nav .item.active:last-child:before {  
	    display: block;  
	}
	.itemTxt{
		height: 80rpx;
		text-align: center;
		line-height: 80rpx;
		font-weight: 500;
		font-size: 28rpx;
		color: rgba(0,0,0,0.4);
	}
	.activeTxt{
		text-align: center;
		height: 96rpx;
		line-height: 96rpx;
		font-weight: bold;
		font-size: 32rpx;
	}
	
	.content{
		width: 100%;
		background: #fff;
	}
</style>

使用组件:

javascript 复制代码
<trapezoidal-tab @changeTab="changeTab" :activeIndex='activeIndex'>
	<template v-slot:left>
		<view>左边部分内容</view>
	</template>
			
	<template v-slot:right>
		<view>右边部分内容</view>
	</template>
</trapezoidal-tab>

const activeIndex = ref(0) //tab选项卡 0:到店取 1:直达送
// 切换tab选项卡
const changeTab =(val)=>{
	activeIndex.value = val
}
相关推荐
明远湖之鱼3 分钟前
从代码到像素:浏览器渲染原理与 React Fiber 架构的深度协作
前端·react.js·浏览器
Knight_AL21 分钟前
Spring Cloud Alibaba 项目中DataSource 配置失败?原来是 application.yml 和 bootstrap.yml 的坑
前端·bootstrap·html
怎么就重名了1 小时前
Kivy的属性系统
java·前端·数据库
hxjhnct2 小时前
JavaScript Promise 的常用API
开发语言·前端·javascript
web小白成长日记2 小时前
前端让我明显感受到了信息闭塞的恐怖......
前端·javascript·css·react.js·前端框架·html
GIS之路2 小时前
GDAL 实现创建几何对象
前端
liulilittle2 小时前
CLANG 交叉编译
linux·服务器·开发语言·前端·c++
自信阿杜3 小时前
跨标签页数据同步完全指南:如何选择最优通信方案
前端·javascript
牛马1113 小时前
WidgetsFlutterBinding.ensureInitialized()在 Flutter Web 端启动流程的影响
java·前端·flutter
Captaincc3 小时前
2025: The year in LLMs
前端·vibecoding