# Tab 标签页
选项卡组件,用于在不同的内容区域之间进行切换。
# 引入
import PressTab from 'press-ui/press-tab/press-tab';
import PressTabs from 'press-ui/press-tabs/press-tabs';
export default {
components: {
PressTab,
PressTabs,
}
}
# 代码演示
# 基础用法
通过active
设定当前激活标签对应的索引值,默认情况下启用第一个标签。
<press-tabs
:active="active"
@change="onChange"
>
<press-tab title="标签 1">
内容 1
</press-tab>
<press-tab title="标签 2">
内容 2
</press-tab>
<press-tab title="标签 3">
内容 3
</press-tab>
<press-tab title="标签 4">
内容 4
</press-tab>
</press-tabs>
export default {
data() {
return {
active: 1,
}
},
methods: {
onChange(value) {
console.log('value', value);
},
}
};
# 通过名称匹配
在标签指定name
属性的情况下,active
的值为当前标签的name
(此时无法通过索引值来匹配标签)。
<press-tabs active="a">
<press-tab title="标签 1" name="a">内容 1</press-tab>
<press-tab title="标签 2" name="b">内容 2</press-tab>
<press-tab title="标签 3" name="c">内容 3</press-tab>
</press-tabs>
# 横向滚动
多于 5 个标签时,Tab 可以横向滚动。
<press-tabs active="{{ active }}">
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
<press-tab title="标签 5">内容 5</press-tab>
<press-tab title="标签 6">内容 6</press-tab>
</press-tabs>
# 禁用标签
设置disabled
属性即可禁用标签。如果需要监听禁用标签的点击事件,可以在press-tabs
上监听disabled
事件。
<press-tabs @disabled="onClickDisabled">
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2" disabled>内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
</press-tabs>
# 样式风格
Tab
支持两种样式风格:line
和card
,默认为line
样式,可以通过type
属性修改样式风格。
<press-tabs type="card">
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
</press-tabs>
# 点击事件
可以在press-tabs
上绑定click
事件,在回调参数的event.detail
中可以取得被点击标签的标题和标识符。
<press-tabs @click="onClick">
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
</press-tabs>
# 粘性布局
通过sticky
属性可以开启粘性布局,粘性布局下,当 Tab 滚动到顶部时会自动吸顶。
<press-tabs sticky>
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
# 切换动画
可以通过animated
来设置是否启用切换 tab 时的动画。
<press-tabs animated>
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
# 滑动切换
通过swipeable
属性可以开启滑动切换标签页。
<press-tabs swipeable>
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
# 嵌套 popup
如果将 press-tabs
嵌套在 press-popup
等会隐藏内容的组件或节点内,当 press-tabs
显示时下划线将不会正常显示。
此时可以通过使用 v-if
手动控制 press-tabs 的渲染来规避这种场景。
<press-popup v-if="show">
<press-tabs v-if="show">
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
</press-popup>
# 自定义标题
通过 use-title-slot
属性以及 title-{index}
的插槽,实现自定义标题。
<press-tabs use-title-slot>
<template #title-0>
<span class="title">Title</span>
<press-icon-plus name="like-o" />
</template>
<template #title-1>
<span class="title">Title 1</span>
<press-icon-plus name="friends-o" />
</template>
<template #title-2>
<span class="title">Title 2</span>
</template>
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
也可以使用 v-for
。
<press-tabs use-title-slot>
<div
v-for="(item, index) of Array(4)"
:key="index"
:slot="`title-${index}`"
>
<span class="title">Title {{ index }}</span>
<press-icon-plus name="like-o" />
</div>
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
# 其他模式
支持 hor/e-sport
模式。
<press-tabs mode="hor">
<press-tab title="标签 1">内容 1</press-tab>
<press-tab title="标签 2">内容 2</press-tab>
<press-tab title="标签 3">内容 3</press-tab>
<press-tab title="标签 4">内容 4</press-tab>
</press-tabs>
# API
# Tabs Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 样式风格,可选值为card | string | line |
color | 标签主题色 | string | #ee0a24 |
active | 当前选中标签的标识符 | string | number | 0 |
duration | 动画时间,单位秒 | number | 0.3 |
line-width | 底部条宽度,默认单位px | string | number | 40px |
line-height | 底部条高度,默认单位px | string | number | 3px |
animated | 是否开启切换标签内容时的转场动画 | boolean | false |
border | 是否展示外边框,仅在 line 风格下生效 | boolean | false |
ellipsis | 是否省略过长的标题文字 | boolean | true |
sticky | 是否使用粘性定位布局 | boolean | false |
swipeable | 是否开启手势滑动切换 | boolean | false |
lazy-render | 是否开启标签页内容延迟渲染 | boolean | true |
offset-top | 粘性定位布局下与顶部的最小距离,单位px | number | - |
swipe-threshold | 滚动阈值,标签数量超过阈值且总宽度超过标签栏宽度时开始横向滚动 | number | 5 |
title-active-color | 标题选中态颜色 | string | - |
title-inactive-color | 标题默认态颜色 | string | - |
z-index | z-index 层级 | number | 1 |
extra-class-prefix | 兼容旧的class ,可传入van- ,不推荐使用 | string | - |
mode | 模式,可传入 hor , e-sport | string | - |
use-title-slot | 是否使用自定义标题插槽 | boolean | false |
# Tab Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
name | 标签名称,作为匹配的标识符 | string | number | 标签的索引值 |
title | 标题 | string | - |
disabled | 是否禁用标签 | boolean | false |
dot | 是否显示小红点 | boolean | - |
info | 图标右上角提示信息 | string | number | - |
title-style | 自定义标题样式 | string | - |
extra-class-prefix | 兼容旧的class ,可传入van- ,不推荐使用 | string | - |
# Tabs Slot
名称 | 说明 |
---|---|
nav-left | 标题左侧内容 |
nav-right | 标题右侧内容 |
# Tab Slot
名称 | 说明 |
---|---|
- | 标签页内容 |
# Tabs Event
事件名 | 说明 | 参数 |
---|---|---|
click | 点击标签时触发 | index: 索引,name:标签标识符,title:标题 |
change | 当前激活的标签改变时触发 | index: 索引,name:标签标识符,title:标题 |
disabled | 点击被禁用的标签时触发 | index: 索引,name:标签标识符,title:标题 |
scroll | 滚动时触发 | { scrollTop: 距离顶部位置, isFixed: 是否吸顶 } |
# 方法
通过 selectComponent 可以获取到 Tabs 实例并调用实例方法。
方法名 | 参数 | 返回值 | 介绍 |
---|---|---|---|
resize | - | - | 外层元素大小或组件显示状态变化时,可以调用此方法来触发重绘 |
# 常见问题
# 组件从隐藏状态切换到显示状态时,底部条位置错误?
Tabs 组件在挂载时,会获取自身的宽度,并计算出底部条的位置。如果组件一开始处于隐藏状态,则获取到的宽度永远为 0,因此无法展示底部条位置。
# 解决方法
方法一,使用 v-if
来控制组件展示,使组件重新初始化。
<press-tabs v-if="show" />
方法二,调用组件的 resize
方法来主动触发重绘。
<press-tabs id="tabs" />
this.selectComponent('#tabs').resize();
# 从vant组件迁移
- 修改组件名,
van-tabs => press-tabs
,van-tab => press-tab
line-width
属性改为number
类型- 可选,为
press-tabs
和press-tab
传入extra-class-prefix="van-"
- 可选,
v-model="tab"
改为:active="tab"
- 可选,
press-tabs
的change
事件参数取值修改,比如:
onTabChange(tab) {
if (this.isMpWeixin) {
tab = tab.detail.name;
}
this.tab = tab;
this.$emit('onTabChange', tab);
},
// 需要改为
onTabChange(tab) {
this.tab = tab.name;
this.$emit('onTabChange', this.tab);
},
line-width
如果传string
类型,可能会报错:
TypeError: Right-hand side of ‘instanceof‘ is not an object
# 延迟加载的 tab 排序问题
对于小程序平台,可以传入 sortIndex
来指定每个 tab
的位置,如:
<press-tabs
swipeable
>
<press-tab
v-if="showLazyTab"
title="Tab A"
:sort-index="0"
>
<div class="content">
Tab A
</div>
</press-tab>
<press-tab
title="Tab B"
:sort-index="1"
>
<div class="content">
Tab B
</div>
</press-tab>
</press-tabs>