259 lines
5.8 KiB
Markdown
259 lines
5.8 KiB
Markdown
# Tab 切换组件
|
||
|
||
一个功能完整的 Tab 切换组件,支持动画过渡、自定义内容和响应式设计。
|
||
|
||
## 功能特性
|
||
|
||
- ✅ **多标签切换**:支持任意数量的标签页切换
|
||
- ✅ **动画指示器**:选中状态下划线,支持平滑滑动动画
|
||
- ✅ **自定义内容**:支持插槽自定义标签内容
|
||
- ✅ **响应式设计**:适配不同屏幕尺寸
|
||
- ✅ **动态宽度**:下划线宽度根据文字宽度动态调整
|
||
- ✅ **事件支持**:完整的切换事件和双向绑定
|
||
- ✅ **主题定制**:支持自定义指示器颜色
|
||
- ✅ **uniapp 兼容**:使用 uniapp 内置组件开发
|
||
|
||
## 基础用法
|
||
|
||
```vue
|
||
<template>
|
||
<Tab
|
||
:tabs="tabList"
|
||
:defaultActive="0"
|
||
@change="handleTabChange"
|
||
/>
|
||
</template>
|
||
|
||
<script setup>
|
||
import Tab from './components/Tab/index.vue'
|
||
|
||
const tabList = ref([
|
||
{ label: '全部订单', value: 'all' },
|
||
{ label: '服务工单', value: 'service' }
|
||
])
|
||
|
||
const handleTabChange = ({ index, item }) => {
|
||
console.log('切换到:', item.label)
|
||
}
|
||
</script>
|
||
```
|
||
|
||
## 自定义标签内容
|
||
|
||
使用 `tab-item` 插槽可以完全自定义标签的显示内容:
|
||
|
||
```vue
|
||
<template>
|
||
<Tab :tabs="customTabs" @change="handleChange">
|
||
<template #tab-item="{ item, index, isActive }">
|
||
<view class="custom-tab">
|
||
<image v-if="item.icon" :src="item.icon" class="tab-icon" />
|
||
<text :class="{ 'active-text': isActive }">{{ item.label }}</text>
|
||
<view v-if="item.badge" class="badge">{{ item.badge }}</view>
|
||
</view>
|
||
</template>
|
||
</Tab>
|
||
</template>
|
||
|
||
<script setup>
|
||
const customTabs = ref([
|
||
{
|
||
label: '待处理',
|
||
value: 'pending',
|
||
icon: '/static/pending.png',
|
||
badge: '3'
|
||
},
|
||
{
|
||
label: '已完成',
|
||
value: 'completed',
|
||
icon: '/static/completed.png'
|
||
}
|
||
])
|
||
</script>
|
||
```
|
||
|
||
## 双向绑定
|
||
|
||
支持 `v-model` 双向绑定当前选中的索引:
|
||
|
||
```vue
|
||
<template>
|
||
<Tab v-model="activeIndex" :tabs="tabList" />
|
||
<text>当前选中索引:{{ activeIndex }}</text>
|
||
</template>
|
||
|
||
<script setup>
|
||
const activeIndex = ref(0)
|
||
const tabList = ref([
|
||
{ label: '标签1', value: 'tab1' },
|
||
{ label: '标签2', value: 'tab2' }
|
||
])
|
||
</script>
|
||
```
|
||
|
||
## 动态标签
|
||
|
||
支持动态添加和删除标签:
|
||
|
||
```vue
|
||
<template>
|
||
<Tab :tabs="dynamicTabs" @change="handleChange" />
|
||
<button @click="addTab">添加标签</button>
|
||
<button @click="removeTab">删除标签</button>
|
||
</template>
|
||
|
||
<script setup>
|
||
const dynamicTabs = ref([
|
||
{ label: '标签1', value: 'tab1' }
|
||
])
|
||
|
||
const addTab = () => {
|
||
const newIndex = dynamicTabs.value.length + 1
|
||
dynamicTabs.value.push({
|
||
label: `标签${newIndex}`,
|
||
value: `tab${newIndex}`
|
||
})
|
||
}
|
||
|
||
const removeTab = () => {
|
||
if (dynamicTabs.value.length > 1) {
|
||
dynamicTabs.value.pop()
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
## Props
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
|------|------|--------|------|
|
||
| tabs | Array | `[{label:'全部订单',value:'all'},{label:'服务工单',value:'service'}]` | 标签数据数组 |
|
||
| defaultActive | Number | `0` | 默认选中的标签索引 |
|
||
| indicatorColor | String | `#007AFF` | 指示器颜色 |
|
||
| modelValue | Number | - | 当前选中索引(用于 v-model) |
|
||
|
||
### tabs 数组项结构
|
||
|
||
```typescript
|
||
interface TabItem {
|
||
label: string // 标签显示文本
|
||
value: string // 标签值
|
||
[key: string]: any // 其他自定义属性
|
||
}
|
||
```
|
||
|
||
## Events
|
||
|
||
| 事件名 | 说明 | 参数 |
|
||
|--------|------|------|
|
||
| change | 标签切换时触发 | `{ index: number, item: TabItem }` |
|
||
| update:modelValue | 用于 v-model 双向绑定 | `index: number` |
|
||
|
||
## Slots
|
||
|
||
| 插槽名 | 说明 | 作用域参数 |
|
||
|--------|------|------------|
|
||
| tab-item | 自定义标签内容 | `{ item: TabItem, index: number, isActive: boolean }` |
|
||
|
||
## 方法
|
||
|
||
通过 `ref` 可以调用组件的方法:
|
||
|
||
```vue
|
||
<template>
|
||
<Tab ref="tabRef" :tabs="tabList" />
|
||
<button @click="switchToTab(1)">切换到第二个标签</button>
|
||
</template>
|
||
|
||
<script setup>
|
||
const tabRef = ref()
|
||
|
||
const switchToTab = (index) => {
|
||
tabRef.value.setActiveIndex(index)
|
||
}
|
||
</script>
|
||
```
|
||
|
||
| 方法名 | 说明 | 参数 | 返回值 |
|
||
|--------|------|------|--------|
|
||
| setActiveIndex | 设置当前选中的标签 | `index: number` | - |
|
||
| getActiveIndex | 获取当前选中的标签索引 | - | `number` |
|
||
| getActiveItem | 获取当前选中的标签项 | - | `TabItem` |
|
||
|
||
## 样式定制
|
||
|
||
### CSS 变量
|
||
|
||
组件支持通过 CSS 变量进行样式定制:
|
||
|
||
```scss
|
||
.tab-container {
|
||
--tab-bg-color: #fff; // 背景色
|
||
--tab-text-color: #666; // 文字颜色
|
||
--tab-active-color: #333; // 选中文字颜色
|
||
--tab-indicator-color: #007AFF; // 指示器颜色
|
||
--tab-border-color: #f0f0f0; // 边框颜色
|
||
}
|
||
```
|
||
|
||
### 自定义主题
|
||
|
||
```vue
|
||
<template>
|
||
<Tab
|
||
:tabs="tabList"
|
||
indicatorColor="#ff4d4f"
|
||
class="custom-tab"
|
||
/>
|
||
</template>
|
||
|
||
<style>
|
||
.custom-tab {
|
||
--tab-indicator-color: #ff4d4f;
|
||
}
|
||
|
||
.custom-tab .tab-text-active {
|
||
color: #ff4d4f;
|
||
}
|
||
</style>
|
||
```
|
||
|
||
## 技术实现
|
||
|
||
- **框架**:Vue 3 组合式 API
|
||
- **平台**:uniapp 跨平台开发
|
||
- **动画**:CSS3 transition + transform
|
||
- **响应式**:CSS media queries
|
||
- **兼容性**:微信小程序、H5、App
|
||
|
||
## 设计规范
|
||
|
||
- 遵循微信小程序设计规范
|
||
- 支持无障碍访问
|
||
- 响应式设计,适配不同设备
|
||
- 流畅的动画过渡效果
|
||
- 一致的视觉风格
|
||
|
||
## 兼容性
|
||
|
||
| 平台 | 支持情况 |
|
||
|------|----------|
|
||
| 微信小程序 | ✅ 完全支持 |
|
||
| H5 | ✅ 完全支持 |
|
||
| App | ✅ 完全支持 |
|
||
| 支付宝小程序 | ✅ 完全支持 |
|
||
| 百度小程序 | ✅ 完全支持 |
|
||
|
||
## 更新日志
|
||
|
||
### v1.0.0
|
||
- ✨ 初始版本发布
|
||
- ✨ 支持基础标签切换功能
|
||
- ✨ 支持动画指示器
|
||
- ✨ 支持自定义标签内容
|
||
- ✨ 支持响应式设计
|
||
- ✨ 支持事件和双向绑定
|
||
|
||
## 备注
|
||
|
||
仅供学习、交流使用,请勿用于商业用途。 |