Tabs 标签页

用于在不同的内容区域之间进行切换,支持滚动、徽标、自定义样式等特性。

代码示例

				
<template>
	<zk-theme type="page" :padding="30" showBack navbarTitle="导航标签栏">
		<!-- 1. 基础用法 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 30rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 24rpx" text="基础用法" />
			<zk-tabs :list="basicList" :current="basic.current" @change="(item) => handleChange(item, 'basic')" />
		</zk-theme>

		<!-- 2. 自定义样式 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 30rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 24rpx" text="自定义样式" />
			<zk-tabs :list="basicList" :current="custom.current" :line-width="30" :line-height="6"
				line-color="linear-gradient(to right, #FF6B6B, #FF8E8E)" :active-style="custom.activeStyle"
				:inactive-style="custom.inactiveStyle" :item-style="custom.itemStyle"
				@change="(item) => handleChange(item, 'custom')" />
		</zk-theme>

		<!-- 3. 等分布局 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 30rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 24rpx" text="等分布局" />
			<zk-tabs :list="shortList" :current="unscroll.current" :scrollable="false"
				:active-style="unscroll.activeStyle" :line-color="'#3B82F6'"
				@change="(item) => handleChange(item, 'unscroll')" />
		</zk-theme>

		<!-- 4. 左右插槽 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 30rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 24rpx" text="左右插槽" />
			<zk-tabs :list="basicList" :current="slot.current" :line-color="'#10B981'"
				@change="(item) => handleChange(item, 'slot')">
				<template #left>
					<view class="slot-btn">
						<zk-text :size="36" color="#666" text="≡" />
					</view>
				</template>
				<template #right>
					<view class="slot-btn">
						<zk-text :size="36" color="#666" text="+" />
					</view>
				</template>
			</zk-tabs>
		</zk-theme>

		<!-- 5. 禁用状态 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 30rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 24rpx" text="禁用状态" />
			<zk-tabs :list="disabledList" :current="disabled.current" :line-color="'#8B5CF6'"
				@change="(item) => handleChange(item, 'disabled')" @click="onDisabledClick" />
		</zk-theme>

		<!-- 6. 横向滚动 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 30rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 8rpx" text="横向滚动" />
			<zk-text type="secondary" :size="24" margin="0 30rpx 24rpx" text="标签较多时自动开启横向滚动" />
			<zk-tabs :list="longList" :current="long.current" :line-color="'#EC4899'"
				@change="(item) => handleChange(item, 'long')" />
		</zk-theme>

		<!-- 7. 动态选项 -->
		<zk-theme type="card" :padding="20" :radius="16" margin="0 0 60rpx 0" :shadow="true">
			<zk-text type="primary" :size="32" weight="bold" margin="0 30rpx 24rpx" text="动态选项" />
			<zk-tabs :list="dynamic.list" :current="dynamic.current" :line-color="'#F59E0B'"
				@change="(item) => handleChange(item, 'dynamic')" />
			<view class="button-group">
				<view class="custom-button" @click="addTab">
					<zk-text color="#fff" :size="26" text="添加标签" />
				</view>
				<view class="custom-button custom-button-plain" @click="removeTab">
					<zk-text color="#4F46E5" :size="26" text="删除标签" />
				</view>
			</view>
		</zk-theme>
	</zk-theme>

</template>

<script>
	export default {
		data() {
			return {
				// 基础列表
				basicList: [{
						name: '关注'
					},
					{
						name: '推荐'
					},
					{
						name: '热门'
					},
					{
						name: '新闻'
					}
				],
				// 短列表
				shortList: [{
						name: '关注',
						badge: {
							content: '99+',
							type: 'danger',
							isDot: false,
							offset: [40, -5],
							max: 99,
							color: '#fff',
							bgColor: '#f00'
						}
					},
					{
						name: '推荐'
					},
					{
						name: '热门'
					},
					{
						name: '热门'
					}
				],
				// 禁用列表
				disabledList: [{
						name: '关注'
					},
					{
						name: '推荐',
						disabled: true
					},
					{
						name: '热门'
					},
					{
						name: '新闻',
						disabled: true
					}
				],
				// 长列表
				longList: Array.from({
					length: 15
				}, (_, i) => ({
					name: `标签${i + 1}`
				})),

				// 各个示例的数据
				basic: {
					current: 0
				},
				custom: {
					current: 0,
					activeStyle: {
						color: '#ff0000',
						fontSize: '28rpx',
						fontWeight: 'bold'
					},
					inactiveStyle: {
						color: '#333333',
						fontSize: '28rpx'
					},
					itemStyle: {
						height: '80rpx',
						padding: '0 30rpx'
					}
				},
				unscroll: {
					current: 0
				},
				slot: {
					current: 0
				},
				disabled: {
					current: 0
				},
				long: {
					current: 0
				},
				dynamic: {
					current: 0,
					list: [{
							name: '标签1'
						},
						{
							name: '标签2'
						},
						{
							name: '标签3'
						}
					]
				},
				custom: {
					current: 0,
					activeStyle: {
						color: '#FF6B6B',
						fontSize: '32rpx',
						fontWeight: '600'
					},
					inactiveStyle: {
						color: '#666666',
						fontSize: '28rpx'
					},
					itemStyle: {
						height: '90rpx',
						padding: '0 40rpx'
					}
				},
				unscroll: {
					current: 0,
					activeStyle: {
						color: '#3B82F6',
						fontWeight: '600'
					}
				}
			}
		},
		methods: {
			// 统一的change处理器
			handleChange(item, type) {
				this[type].current = item.index
			},

			// 禁用项点击处理
			onDisabledClick(item) {
				if (item.disabled) {
					uni.showToast({
						title: '该项已禁用',
						icon: 'none'
					})
				}
			},

			// 动态添加标签
			addTab() {
				const newLength = this.dynamic.list.length + 1
				this.dynamic.list.push({
					name: `标签${newLength}`
				})
			},

			// 动态删除标签
			removeTab() {
				if (this.dynamic.list.length > 1) {
					this.dynamic.list.pop()
					if (this.dynamic.current >= this.dynamic.list.length) {
						this.dynamic.current = this.dynamic.list.length - 1
					}
				}
			}
		}
	}
</script>

<style lang="scss">
	/* #ifndef APP-NVUE */
	.slot-btn {
		padding: 0 20rpx;
	}

	.button-group {
		display: flex;
		justify-content: center;
		padding: 30rpx 20rpx 10rpx;
		gap: 20rpx;
	}

	.custom-button {
		padding: 16rpx 32rpx;
		background: #4F46E5;
		border-radius: 8rpx;
		transition: all 0.3s;

		&-plain {
			background: transparent;
			border: 2rpx solid #4F46E5;
		}

		&:active {
			transform: scale(0.98);
			opacity: 0.9;
		}
	}

	/* #endif */

	/* #ifdef APP-NVUE */
	.slot-btn {
		padding: 0 20rpx;
	}

	.button-group {
		flex-direction: row;
		justify-content: center;
		padding: 30rpx 20rpx 10rpx;
	}

	.custom-button {
		padding: 16rpx 32rpx;
		background-color: #4F46E5;
		border-radius: 8rpx;
		margin-right: 20rpx;

		&-plain {
			background-color: transparent;
			border-width: 2rpx;
			border-style: solid;
			border-color: #4F46E5;
		}
	}

	/* #endif */
</style>
			

API

Props 属性

参数 说明 类型 默认值
list 标签列表 Array []
current 当前选中标签的索引 number 0
scrollable 是否可以滚动 boolean false
theme 主题类型 string default
key-name 从列表项中读取的文字键名 string name
active-color 选中标签的文字颜色 string #2b5aed
inactive-color 未选中标签的文字颜色 string #606266
line-color 下划线颜色 string 同active-color
line-width 下划线宽度,单位rpx string / number 40
line-height 下划线高度,单位rpx string / number 6
line-radius 下划线圆角,单位rpx string / number 3
active-style 选中标签的样式对象 Object { color: primary, fontWeight: 'bold' }
inactive-style 未选中标签的样式对象 Object { color: textSecondary, fontWeight: 'normal' }
item-style 标签项的自定义样式 Object {}

Events 事件

事件名 说明 回调参数
change 切换标签时触发 { index: number, item: object }
click 点击标签时触发 { index: number, item: object }
longPress 长按标签时触发 { index: number, item: object }

Slots 插槽

名称 说明
left 自定义左侧内容
right 自定义右侧内容

数据结构

list: [
      {
          name: string,      // 显示的文字
          badge: {           // 徽标配置
              content: string | number,  // 徽标内容
              type: string,  // 徽标类型
              isDot: boolean,// 是否显示为小圆点
              offset: array, // 偏移量
              max: number,   // 最大值
              color: string, // 文字颜色
              bgColor: string// 背景颜色
          },
          disabled: boolean  // 是否禁用
      }
  ]