自定义导航栏
微信小程序 navigationStyle: "custom" 下需自行处理状态栏高度和胶囊避让。项目封装了 useNavbar composable 和 custom-navbar 组件,页面直接用组件即可,一般不需要手动调 composable。
custom-navbar 组件
vue
<custom-navbar title="页面标题" fixed placeholder />1
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| title | 标题文字 | string | "" |
| titleColor | 标题颜色 | string | var(--color-text) |
| bgColor | 背景色 | string | var(--color-bg) |
| iconColor | 图标颜色 | string | var(--color-text) |
| showBack | 显示返回按钮 | boolean | true |
| showHome | 显示首页按钮 | boolean | false |
| backIcon | 返回按钮图标名 | string | "arrow-left" |
| backIconSize | 返回按钮图标大小 | string | "40rpx" |
| fixed | 固定到顶部 | boolean | true |
| placeholder | fixed 时自动撑出等高占位 | boolean | false |
| navBarHeight | 导航栏内容高度,仅 H5/App 生效(小程序走胶囊计算) | number | 44 |
Events
| 事件 | 说明 |
|---|---|
back | 点击返回按钮 |
home | 点击首页按钮 |
Slots
| 插槽 | 说明 |
|---|---|
left | 返回/首页按钮之后 |
center | 标题之后,用 #center 可替换标题 |
right | 右侧区域 |
useNavbar composable
需要手动控制布局(如沉浸式、scroll-view 独立滚动)时使用:
ts
import { useNavbar } from "@/composables/useNavbar"
const { totalHeight, contentPaddingTop } = useNavbar()
// TabBar 页面
const navbar = useNavbar({ hasTabbar: true })1
2
3
4
5
6
2
3
4
5
6
返回值
| 属性 | 类型 | 说明 |
|---|---|---|
statusBarHeight | Ref<number> | 状态栏高度 |
navBarHeight | number | 导航栏内容高度(H5/App 为 44,小程序为胶囊计算值) |
totalHeight | ComputedRef<number> | 导航栏总高度(状态栏 + 内容高度) |
contentPaddingTop | ComputedRef<string> | totalHeight + "px",直接用作 paddingTop |
safeAreaBottom | Ref<number> | 安全区域底部高度 |
menuButton | Ref<MenuButtonRect | null> | 胶囊按钮位置信息 |
menuButtonWidth | ComputedRef<number> | 胶囊按钮宽度 |
menuButtonLeft | ComputedRef<number> | 胶囊按钮左侧距屏幕左边距离 |
menuButtonRightGap | ComputedRef<number> | 胶囊按钮右侧距屏幕右边距离 |
contentWidth | ComputedRef<number> | 内容区域可用宽度(避开胶囊) |
platform | Ref<string> | 平台标识 |
windowWidth | Ref<number> | 窗口宽度 |
init | () => void | 重新初始化(setup 阶段已自动调用) |
场景示例
标准用法
导航栏固定,内容从下方开始:
vue
<custom-navbar title="用户管理" fixed placeholder />1
沉浸式
轮播图铺到顶部,导航栏透明叠加,内容区手动 paddingTop:
vue
<template>
<view class="hero" :style="{ paddingTop: navbar.totalHeight.value + 'px' }">
<custom-navbar
fixed :placeholder="false"
bg-color="transparent"
title-color="var(--color-text-inverse)"
icon-color="var(--color-text-inverse)"
:show-back="false"
/>
<wd-swiper :list="swiperList" autoplay />
</view>
</template>
<script setup>
import { useNavbar } from "@/composables/useNavbar"
const navbar = useNavbar({ hasTabbar: true })
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
常见坑点
| 坑点 | 解决 |
|---|---|
| 内容与导航栏重叠 | 用 placeholder,或 paddingTop: totalHeight |
| 按钮与胶囊重叠 | 用 menuButtonRightGap 避让,或直接用 custom-navbar(已内置) |
getMenuButtonBoundingClientRect 返回 0 | iOS 预览偶发,useNavbar 内置 6 次重试 + 默认值兜底 |
| 页面出现多余滚动 | 不要无脑 min-height: 100vh,让内容自然撑开 |
| 状态栏高度不准 | 不要用 CSS 变量 --status-bar-height(小程序端固定 25px),用 useNavbar 动态获取 |
