Skip to content

自定义 TabBar

项目通过 custom: true 开启微信小程序自定义 TabBar 模式,用 Wot Design Uni 的 wd-tabbar 组件替代原生底部导航栏,实现主题联动和灵活定制。

实现原理

自定义 TabBar 涉及三个文件:

文件职责
pages.config.ts声明 TabBar 页面列表,设置 custom: true
src/layouts/tabbar.vue渲染 wd-tabbar 组件,处理页面切换和主题注入
src/composables/useTabbar.tsTabBar 状态管理(徽标数字、激活切换,可选)

配置页面列表

pages.config.ts 中声明 TabBar 页面,custom: true 开启自定义模式:

ts
// pages.config.ts
export default defineUniPages({
  tabBar: {
    custom: true,   // 开启自定义 TabBar
    height: "0",    // 原生 TabBar 高度设为 0,完全由自定义组件接管
    list: [
      { pagePath: "pages/index/index" },
      { pagePath: "pages/work/index" },
      { pagePath: "pages/mine/index" },
    ],
  },
})

list 中的 pagePath 决定哪些页面是 TabBar 页面。colorselectedColor 等原生样式配置在自定义模式下不生效,实际颜色由 tabbar.vue 中的 Wot UI 组件控制。

tabbar 布局组件

TabBar 页面在 definePage() 中声明 layout: "tabbar" 即可使用:

vue
<script setup lang="ts">
definePage({
  name: "home",
  style: { navigationStyle: "custom" },
  layout: "tabbar",
})
</script>

tabbar.vue 组件做了三件事:

  1. 渲染 wd-tabbar — 底部固定、安全区适配、带边框
  2. 初始化激活项 — 通过 getCurrentPages() 获取当前页面路径,匹配对应的 TabBar 项
  3. 处理切换 — 调用 uni.switchTab 跳转目标页面
vue
<!-- src/layouts/tabbar.vue(核心逻辑) -->
<wd-tabbar
  v-model="active"
  bordered
  safe-area-inset-bottom
  fixed
  @change="handleTabbarChange"
>
  <wd-tabbar-item
    v-for="item in tabbarList"
    :key="item.name"
    :name="item.name"
    :title="item.title"
    :icon="item.icon"
  />
</wd-tabbar>

TabBar 配置项在组件内定义,name 与页面路径一一对应:

ts
const tabbarList = [
  { name: "/pages/index/index", title: "首页", icon: "home" },
  { name: "/pages/work/index", title: "工作台", icon: "apps" },
  { name: "/pages/mine/index", title: "我的", icon: "user" },
]

主题联动

tabbar.vue 通过 useThemeStore 注入主题:

vue
<wd-config-provider
  :theme-vars="themeVars"
  :theme="theme === 'dark' ? 'dark' : ''"
>
  <slot />
  <wd-tabbar ... />
</wd-config-provider>

切换明暗模式时,TabBar 会自动跟随主题变化。

useTabbar composable

composables/useTabbar.ts 提供独立的 TabBar 状态管理,支持徽标数字和激活切换:

ts
import { useTabbar } from "@/composables/useTabbar"

const { tabbarList, activeTabbar, setTabbarItem, setTabbarItemActive } = useTabbar()

// 设置工作台徽标数字
setTabbarItem("work", 5)

// 切换激活项
setTabbarItemActive("mine")

// 重置状态
resetTabbar()
方法 / 属性说明
tabbarListTabBar 项列表(computed)
activeTabbar当前激活项
setTabbarItem(name, value)设置徽标数字
getTabbarItemValue(name)获取徽标数字
setTabbarItemActive(name)切换激活项
resetTabbar()重置为默认状态

默认配置三个页签:homeworkmine。支持单例模式(默认)和独立实例:

ts
// 独立实例(不共享全局状态)
const tabbar = useTabbar({ singleton: false })

新增 / 修改 TabBar 页签

  1. pages.config.tstabBar.list 中添加页面路径
  2. src/layouts/tabbar.vuetabbarList 数组中添加对应项(namepagePath 一致)
  3. 如果使用了 useTabbar,同步修改 DEFAULT_TABBAR_ITEMS

常见问题

问题原因处理方式
TabBar 不显示页面未声明 layout: "tabbar"definePage() 中添加 layout: "tabbar"
TabBar 页签不匹配tabbar.vue 中的 namepagePath 不一致确保两边路径完全一致
APP 端出现原生 TabBarApp 端会显示原生 TabBartabbar.vue 已内置 uni.hideTabBar() 处理
激活项不对页面切换后未更新激活状态onShow 中已调用 initActive() 重新匹配

相关文档

基于 MIT 许可发布 · 如需部署协助或二开定制,请查看 支持与合作