介绍
固定在页面底部的导航栏,用于切换不同的页面。
代码演示
基础使用
使用 v-model 绑定当前选中的标签。
vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon name="chat-dots-fill" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon name="person-fill" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref(0)
</script>vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon name="chat-dots-fill" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon name="person-fill" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref(0)
</script>自定义图标
通过 icon 属性自定义图标。
vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon v-if="value === 0" name="house-door-fill" />
<demo-icon v-else name="house-door" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon v-if="value === 1" name="cart-fill" />
<demo-icon v-else name="cart" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon v-if="value === 2" name="chat-dots-fill" />
<demo-icon v-else name="chat-dots" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon v-if="value === 3" name="person-fill" />
<demo-icon v-else name="person" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref(0)
</script>vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon v-if="value === 0" name="house-door-fill" />
<demo-icon v-else name="house-door" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon v-if="value === 1" name="cart-fill" />
<demo-icon v-else name="cart" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon v-if="value === 2" name="chat-dots-fill" />
<demo-icon v-else name="chat-dots" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon v-if="value === 3" name="person-fill" />
<demo-icon v-else name="person" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref(0)
</script>自定义颜色
使用 color 属性设置未选中标签的颜色。 使用 activeColor 属性设置选中标签的颜色。
vue
<template>
<s-tabbar v-model="value" active-color="var(--s-color-danger)">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon name="chat-dots-fill" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon name="person-fill" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref(0)
</script>vue
<template>
<s-tabbar v-model="value" active-color="var(--s-color-danger)">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon name="chat-dots-fill" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon name="person-fill" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref(0)
</script>徽标
可以使用 Badge 组件包裹图标。
vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<s-badge :value="5">
<demo-icon name="chat-dots-fill" />
</s-badge>
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<s-badge dot>
<demo-icon name="person-fill" />
</s-badge>
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const value = ref(0)
</script>vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<s-badge :value="5">
<demo-icon name="chat-dots-fill" />
</s-badge>
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<s-badge dot>
<demo-icon name="person-fill" />
</s-badge>
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="js">
import { ref } from 'vue'
const value = ref(0)
</script>中间鼓起
通过覆盖默认插槽自定义标签结构和样式。
vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item @click="toast('点击了添加按钮')">
<div class="bulge">
<div class="cover"></div>
<div class="button">
<Plus class="text-5xl" />
</div>
</div>
<span class="text">添加</span>
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon name="chat-dots-fill" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon name="person-fill" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { toast } from 'sard'
import { Plus } from '@sard/icons'
const value = ref(0)
</script>
<style lang="scss" scoped>
.bulge {
position: absolute;
top: 0;
transform-origin: top center;
transform: scale(0.5) translateY(-33%);
display: flex;
justify-content: center;
align-items: center;
width: 96px;
height: 96px;
border-radius: 50%;
background-color: var(--s-tabbar-bg);
box-shadow: inset 0 0 0 1px var(--s-border-color);
&:active {
opacity: 0.8;
}
}
.cover {
position: absolute;
top: 33%;
width: 100%;
height: 70%;
transform: translateY(1px);
background-color: var(--s-tabbar-bg);
}
.button {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 76px;
height: 76px;
border-radius: 50%;
background-color: var(--s-color-primary);
color: var(--s-white);
}
.text {
position: relative;
margin-top: auto;
margin-bottom: 5px;
}
</style>vue
<template>
<s-tabbar v-model="value">
<s-tabbar-item :value="0" label="首页" #icon>
<demo-icon name="house-door-fill" />
</s-tabbar-item>
<s-tabbar-item :value="1" label="购物车" #icon>
<demo-icon name="cart-fill" />
</s-tabbar-item>
<s-tabbar-item @click="toast('点击了添加按钮')">
<div class="bulge">
<div class="cover"></div>
<div class="button">
<Plus class="text-5xl" />
</div>
</div>
<span class="text">添加</span>
</s-tabbar-item>
<s-tabbar-item :value="2" label="消息" #icon>
<demo-icon name="chat-dots-fill" />
</s-tabbar-item>
<s-tabbar-item :value="3" label="我的" #icon>
<demo-icon name="person-fill" />
</s-tabbar-item>
</s-tabbar>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { toast } from 'sard'
import { Plus } from '@sard/icons'
const value = ref(0)
</script>
<style lang="scss" scoped>
.bulge {
position: absolute;
top: 0;
transform-origin: top center;
transform: scale(0.5) translateY(-33%);
display: flex;
justify-content: center;
align-items: center;
width: 96px;
height: 96px;
border-radius: 50%;
background-color: var(--s-tabbar-bg);
box-shadow: inset 0 0 0 1px var(--s-border-color);
&:active {
opacity: 0.8;
}
}
.cover {
position: absolute;
top: 33%;
width: 100%;
height: 70%;
transform: translateY(1px);
background-color: var(--s-tabbar-bg);
}
.button {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 76px;
height: 76px;
border-radius: 50%;
background-color: var(--s-color-primary);
color: var(--s-white);
}
.text {
position: relative;
margin-top: auto;
margin-bottom: 5px;
}
</style>API
TabbarProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| model-value | 当前选中标签的 value 属性 | number | string | - |
| color | 未选中标签的颜色 | string | - |
| active-color | 选中标签的颜色 | string | - |
| bordered | 是否显示外边框 | boolean | true |
| fixed | 是否固定到页面底部 | boolean | false |
| safe-area-inset-bottom | 是否开启底部安全区适配 | boolean | false |
TabbarSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
TabbarEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| update:modelValue | 切换标签时触发 | (value: number | string) => void |
| change | 切换标签时触发 | (value: number | string) => void |
TabbarItemProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| value | 标签唯一标识符 | string | number | - |
| label | 要显示的标签文本 | string | - |
TabbarItemSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义文本内容 | - |
| icon | 自定义图标 | {active: boolean} |
TabbarItemEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| click | 点击标签时触发 | (event: MouseEvent) => void |
主题定制
样式变量
| CSS 变量 | 值 |
|---|---|
--s-tabbar-z-index | var(--s-z-index-secondary) |
--s-tabbar-height | 50px |
--s-tabbar-border-color | var(--s-border-color) |
--s-tabbar-bg | var(--s-bg-color-container) |
--s-tabbar-color | var(--s-text-color-secondary) |
--s-tabbar-item-color-active | var(--s-color-primary) |
--s-tabbar-item-icon-margin-bottom | var(--s-size-2xs) |
--s-tabbar-item-icon-font-size | var(--s-size-lg) |
--s-tabbar-item-label-font-size | var(--s-font-size-sm) |