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
}
相关推荐
小彭努力中1 天前
205.Vue3 + OpenLayers:加载动画,采用 CSS 的 @keyframes 方式
前端·css·vue.js·openlayers·cesium·webgis
木斯佳1 天前
前端八股文面经大全:上海威派格前端实习(2026-05-07)·面经深度解析
前端
_Twink1e1 天前
基于Vue的纯前端的库存销售系统
前端·vue.js·vue·web
棋宣1 天前
uni-app编译到微信小程序中,父传子props首次传递数据不接收的bug
微信小程序·uni-app·bug
幽络源小助理1 天前
音频在线剪切助手网页版源码 – 纯前端HTML单文件免费分享
前端·音视频
陈振wx:zchen20081 天前
前端-面试题-Vue
前端·vue.js
计算机安禾1 天前
【c++面向对象编程】第5篇:类与对象(四):赋值运算符重载
java·前端·c++
Moment1 天前
从 beginWork 到 completeWork,Fiber 树是怎么“盖”出来的❓❓❓
前端·javascript·面试
Java面试题总结1 天前
.NET 8 Web开发入门(三):解构引擎——依赖注入(DI)与中间件管道
前端·中间件·.net
不会写DN1 天前
为什么需要 @types/react? 解决“无法找到模块 react 的声明文件”报错
前端·react.js·前端框架