当前位置: 首页 > article >正文

UniApp微信小程序自定义导航栏实现

UniApp微信小程序自定义导航栏

在UniApp开发微信小程序时,页面左上角默认有一个返回按钮(在导航栏左侧),但有时我们需要自定义这个按钮的样式和功能,同时保持与导航栏中间的标题和右侧胶囊按钮(药丸屏)的高度一致。

微信小程序的导航栏分为三部分:左侧(返回和主页)、中间(标题)、右侧(胶囊按钮)。自定义左侧按钮时,我们需要注意以下几点:

  1. 微信小程序的导航栏是原生的,我们无法直接修改原生返回按钮的样式,因此常见的做法是隐藏原生导航栏,使用自定义导航栏。

  2. 自定义导航栏需要计算导航栏的高度,尤其是要考虑到不同机型的适配(如iPhone的刘海屏、状态栏高度等)。

  3. 右侧的胶囊按钮(药丸屏)的尺寸和位置是固定的,我们可以通过微信提供的API获取其位置信息,以便让自定义按钮与胶囊按钮对齐。

具体步骤如下:

1. 隐藏原生导航栏

pages.json中,设置页面或全局的导航栏为自定义:


{"pages": [{"path": "pages/index/index","style": {"navigationStyle": "custom"  // 使用自定义导航栏}}],// 或者全局设置"globalStyle": {"navigationStyle": "custom"}}

2. 在页面中编写自定义导航栏

在页面的vue文件中,我们需要自己编写一个导航栏组件,通常放在页面顶部。

3. 获取状态栏高度和胶囊按钮位置

我们可以使用uni.getSystemInfoSync()来获取状态栏高度,以及使用uni.getMenuButtonBoundingClientRect()来获取胶囊按钮的位置信息。

示例代码:


const systemInfo = uni.getSystemInfoSync();const menuButtonInfo = uni.getMenuButtonBoundingClientRect();// 状态栏高度(手机顶部状态栏区域的高度)const statusBarHeight = systemInfo.statusBarHeight;// 胶囊按钮距离顶部的距离(通常比状态栏高度多一点点,具体以获取到的为准)const menuButtonTop = menuButtonInfo.top;// 导航栏高度 = 胶囊按钮高度 + (胶囊按钮上边距 - 状态栏高度) * 2// 因为胶囊按钮上下有间隙,所以导航栏高度可以这样计算:const navBarHeight = (menuButtonTop - statusBarHeight) * 2 + menuButtonInfo.height;// 整个自定义导航栏的高度 = 状态栏高度 + 导航栏高度const customBarHeight = statusBarHeight + navBarHeight;

4. 布局自定义导航栏

在模板中,我们使用计算得到的高度来设置导航栏的样式,确保高度与原生导航栏一致。

左侧按钮的位置需要与胶囊按钮对齐(垂直方向),因此我们可以将左侧按钮的顶部设置为menuButtonTop(胶囊按钮的顶部位置),然后通过调整上边距或使用绝对定位来实现。

示例模板结构:


<template><view><!-- 自定义导航栏 --><view class="custom-nav" :style="{ height: customBarHeight + 'px', paddingTop: statusBarHeight + 'px' }"><!-- 左侧按钮 --><view class="left-btn" :style="{ top: menuButtonTop + 'px' }" @click="goHome"><!-- 这里可以放置自定义图标或文字 --><image src="/static/home.png" mode="aspectFit"></image></view><!-- 中间标题 --><view class="title" :style="{ height: navBarHeight + 'px', lineHeight: navBarHeight + 'px' }">标题</view><!-- 右侧通常不需要添加内容,因为胶囊按钮是原生的,但我们也可以自定义右侧内容,但要注意与胶囊按钮的位置不重叠 --></view><!-- 页面内容,需要设置一个上边距,避免被导航栏覆盖 --><view :style="{ marginTop: customBarHeight + 'px' }">... 页面内容 ...</view></view></template>

样式示例(使用scss):


.custom-nav {position: fixed;top: 0;left: 0;width: 100%;box-sizing: border-box;background-color: #ffffff;z-index: 999;.left-btn {position: absolute;left: 10px;height: 30px; // 胶囊按钮的高度可以通过menuButtonInfo.height获取,这里假设30pxdisplay: flex;align-items: center;justify-content: center;// 通过top定位垂直位置,与胶囊按钮对齐image {width: 20px;height: 20px;}}.title {text-align: center;font-size: 16px;}}

5. 自定义按钮的功能

goHome方法中,我们可以实现跳转到首页的功能:


methods: {goHome() {uni.reLaunch({url: '/pages/index/index'});}}

注意事项:

  • 由于自定义导航栏是固定在顶部的,页面内容需要设置一个上边距(等于自定义导航栏的高度),避免内容被导航栏覆盖。

  • 不同机型的胶囊按钮位置可能略有差异,所以一定要动态获取胶囊按钮的位置信息。

  • 在微信开发者工具中,胶囊按钮的位置信息可能与真机有差异,建议在真机测试。

通过以上步骤,我们就可以自定义一个与中间标题和右侧胶囊按钮高度一致的左侧按钮,并实现自定义功能。

在 UniApp 开发微信小程序时,要自定义左上角返回按钮并保持与标题栏、右侧胶囊按钮高度对齐,需使用自定义导航栏方案。以下是完整实现步骤:

核心思路
隐藏原生导航栏,使用自定义导航栏组件

精确计算布局尺寸,匹配微信胶囊按钮位置

使用绝对定位控制自定义按钮位置

实现步骤
1. 配置全局自定义导航栏(pages.json)

{"globalStyle": {"navigationStyle": "custom","transparentTitle": "always","navigationBarTextStyle": "black"}
}

2. 创建自定义导航栏组件(components/custom-navbar.vue)

<template><view class="custom-navbar"><!-- 状态栏占位 --><view :style="{ height: statusBarHeight + 'px' }"></view><!-- 导航栏主体 --><view class="navbar-content" :style="{ height: navBarHeight + 'px' }"><!-- 左侧自定义按钮 --><view class="custom-home-btn" :style="btnStyle"@click="handleHomeClick"><image src="/static/home-icon.png" class="icon" /></view><!-- 标题居中 --><view class="title" :style="titleStyle">{{ title }}</view></view></view>
</template><script>
export default {props: {title: String},data() {return {statusBarHeight: 20, // 默认值navBarHeight: 44,    // 默认值menuButtonInfo: null};},computed: {// 按钮样式计算(核心)btnStyle() {if (!this.menuButtonInfo) return {};return {width: '30px',height: this.menuButtonInfo.height + 'px',top: this.menuButtonInfo.top + 'px'};},// 标题位置适配titleStyle() {return {height: this.menuButtonInfo.height + 'px',lineHeight: this.menuButtonInfo.height + 'px'};}},mounted() {this.initSystemInfo();},methods: {initSystemInfo() {const systemInfo = uni.getSystemInfoSync();this.statusBarHeight = systemInfo.statusBarHeight;// 获取微信胶囊按钮位置const menuButtonInfo = uni.getMenuButtonBoundingClientRect();this.menuButtonInfo = menuButtonInfo;// 计算导航栏高度 = 胶囊按钮高度 + (胶囊按钮上间距 - 状态栏高度) * 2this.navBarHeight = menuButtonInfo.height + (menuButtonInfo.top - systemInfo.statusBarHeight) * 2;},handleHomeClick() {// 自定义按钮功能(示例:返回首页)uni.reLaunch({ url: '/pages/index/index' });}}
};
</script><style scoped>
.custom-navbar {position: fixed;top: 0;left: 0;right: 0;z-index: 9999;background: white;
}.navbar-content {position: relative;display: flex;justify-content: center;align-items: center;
}.custom-home-btn {position: absolute;left: 15px;display: flex;align-items: center;justify-content: center;z-index: 10;
}.icon {width: 22px;height: 22px;
}.title {font-size: 16px;font-weight: 500;max-width: 60%;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}
</style>

3. 在页面中使用自定义导航栏

<template><view><!-- 引入自定义导航栏 --><custom-navbar title="我的页面" /><!-- 页面内容 (需要设置顶部内边距) --><view :style="{ paddingTop: navBarTotalHeight + 'px' }"><!-- 页面内容... --></view></view>
</template><script>
import customNavbar from '@/components/custom-navbar.vue'export default {components: { customNavbar },data() {return {// 计算:状态栏高度 + 导航栏高度navBarTotalHeight: 64 // 默认值}},onLoad() {this.calcNavbarHeight()},methods: {calcNavbarHeight() {const systemInfo = uni.getSystemInfoSync()const menuButtonInfo = uni.getMenuButtonBoundingClientRect()this.navBarTotalHeight = systemInfo.statusBarHeight + menuButtonInfo.height + (menuButtonInfo.top - systemInfo.statusBarHeight) * 2}}
}
</script>

关键点说明
胶囊按钮对齐原理:

  • 使用 uni.getMenuButtonBoundingClientRect() 获取胶囊按钮的精确位置信息
  • 通过公式计算导航栏高度:胶囊高度 + (胶囊上间距 - 状态栏高度) × 2
  • 按钮垂直定位使用胶囊按钮的 top 值

响应式处理:

  • 不同机型适配(iPhone 刘海屏、Android 等)
  • 小程序右上角胶囊按钮位置是固定的
  • 页面滚动时导航栏保持固定定位

样式定制:

  • 替换 /static/home-icon.png 为自定义图标
  • 调整 left 值控制水平位置
  • 修改按钮的宽高和图标尺寸

注意事项

  1. **真机测试:**微信开发者工具中的胶囊位置与真机可能有差异
  2. **iOS 安全区域:**iPhone X 及以上机型需要处理底部安全区域
  3. **页面滚动:**页面内容需要设置 padding-top 避免内容被导航栏遮挡
  4. **组件复用:**建议封装成全局组件减少重复代码

通过此方案,自定义按钮可以实现:

  1. 与原生胶囊按钮完美对齐 ✅
  2. 支持自定义图标和点击事件 ✅
  3. 完美适配不同机型 ✅
  4. 保持原生导航栏流畅体验 ✅

相关文章:

UniApp微信小程序自定义导航栏实现

UniApp微信小程序自定义导航栏 在UniApp开发微信小程序时&#xff0c;页面左上角默认有一个返回按钮&#xff08;在导航栏左侧&#xff09;&#xff0c;但有时我们需要自定义这个按钮的样式和功能&#xff0c;同时保持与导航栏中间的标题和右侧胶囊按钮&#xff08;药丸屏&…...

【Ubuntu】Ubuntu网络管理

Ubuntu 网络管理 ubuntu/debian 中的网络管理 NetworkManager,使用nmcli查询与操作网络配置 /run/NetworkManager/no-stub-resolv.conf 对应命令行例子: nmcli device showsystemd-networkd,使用netplan的yaml文件来配置网络 /usr/lib/systemd/systemd-networkdsystemd-resol…...

GitHub 趋势日报 (2025年05月27日)

本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1Fosowl/agenticSeek完全本地的马努斯AI。没有API&#xff0c;没有200美元的每…...

VR视角下,浙西南革命的热血重生​

VR 浙西南革命项目依托先进的 VR 技术&#xff0c;为浙西南革命历史的展示开辟了一条全新的道路 &#xff0c;打破了时间与空间的限制&#xff0c;使革命历史变得触手可及。​ &#xff08;一&#xff09;沉浸式体验革命场景​ 借助 VR 技术&#xff0c;在 VR 浙西南革命的展示…...

深入解析Kafka JVM堆内存:优化策略与监控实践

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

【高级终端Termux】在安卓手机/平板上使用Termux 搭建 Debian 环境并运行 PC 级 Linux 应用教程(含安装WPS,VS Code)

Termux 搭建 Debian 环境并运行 PC 级 Linux 应用教程 一、前言 1. 背景 众所周知&#xff0c;最新搭载澎湃OS和鸿蒙OS的平板都内置了PC级WPS&#xff0c;办公效率直接拉满&#xff08;板子终于从“泡面盖”升级为“生产力”了&#xff09;。但问题来了&#xff1a;如果不是这…...

基于BERT-Prompt的领域句子向量训练方法

基于BERT-Prompt的领域句子向量训练方法 一、核心原理:基于BERT-Prompt的领域句子向量训练方法 论文提出一种结合提示学习(Prompt Learning)和BERT的领域句子向量训练方法,旨在解决装备保障领域文本的语义表示问题。核心原理如下: 以下通过具体例子解释传统词向量方法和…...

高频面试--redis

Reids 1. 常见的数据结构&#xff08;string, list, hash, set, zset&#xff09; 答法模板&#xff1a; Redis 提供五种核心数据结构&#xff1a; String&#xff1a;最基本的类型&#xff0c;支持整数、自增、自减、位操作。 List&#xff1a;双端链表&#xff0c;支持消息…...

CRMEB 单商户Java版 v2.3公测版发布,欢迎体验!

当商城管理后台一成不变时&#xff0c;你是否也有过换换风格的想法&#xff1f; 当商城流量激增时&#xff0c;你是否也希望随时观察服务器负载状况&#xff0c;确保系统稳定运行&#xff1f; CRMEB单商户Java版v2.3公测版发布&#xff0c;更新200管理后台页面、弹窗&#xf…...

(四) 本地YARN集群的部署

一、部署说明 Hadoop YARN分布式资源调度&#xff0c;会启动&#xff1a; ResourceManager进程作为管理节点NodeManager进程作为工作节点ProxyServer、JobHistoryServer这两个辅助节点 二、配置文件 在 $HADOOP_HOME/etc/hadoop 文件夹内&#xff0c;修改&#xff1a; 1.m…...

华为OD机试真题——求最多可以派出多少支队伍(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

《软件工程》第 12 章 - 软件测试

软件测试是确保软件质量的关键环节&#xff0c;它通过执行程序来发现错误&#xff0c;验证软件是否满足需求。本章将依据目录&#xff0c;结合 Java 代码示例、可视化图表&#xff0c;深入讲解软件测试的概念、过程、方法及实践。 12.1 软件测试的概念 12.1.1 软件测试的任务 …...

消息队列-kafka为例

目录 消息队列应用场景和基础知识MQ常见的应用场景MQ消息队列的两种消息模式如何保证消息队列的高可用&#xff1f;如何保证消息不丢失&#xff1f;如何保证消息不被重复消费&#xff1f;如何保证消息消费的幂等性&#xff1f;重复消费的原因解决方案 如何保证消息被消费的顺序…...

学习STC51单片机20(芯片为STC89C52RCRC)

每日一言 生活不会一帆风顺&#xff0c;但你的勇敢能让风浪变成风景。 串口助手的界面就等于是pc端的页面设置的是pc端的波特率等等参数 程序里面的是单片机的波特率等等参数 串口助手是 PC 端软件 串口助手&#xff08;如 STC-ISP&#xff09;是运行在 PC 上的工具&#x…...

链路追踪神器zipkin安装详细教程教程

今天分享下zipkin的详细安装教程&#xff0c;具体代码demo可以参考我上篇文章&#xff1a;Spring Cloud Sleuth与Zipkin深度整合指南&#xff1a;微服务链路追踪实战-CSDN博客 一、Zipkin是什么&#xff1f; Zipkin是由Twitter开源的一款分布式追踪系统&#xff08;现由OpenZ…...

RabbitMQ备份与恢复技术详解:策略、工具与最佳实践

RabbitMQ作为广泛使用的消息中间件&#xff0c;其高可用性和数据持久化能力使其成为分布式系统的核心组件。然而&#xff0c;硬件故障、人为误操作或灾难性事件仍可能导致数据丢失或服务中断。因此&#xff0c;建立可靠的备份与恢复机制是运维工作的关键环节。本文基于RabbitMQ…...

bug: uniCloud 查询数组字段失败

问题根源&#xff1a;使用了支付宝云 官方说&#xff1a;2024年11月之后创建的新的支付宝云空间&#xff0c;数组字段查询强制必须设置 array 类型的索引 布尔类型的查询&#xff0c;强制必须设置 bool 类型的索引。 方案一&#xff1a;找到云服务空间-》云数据库-》对应的表-…...

Php JIT 使用详解

简介 PHP 8 引入的 JIT&#xff08;Just-In-Time 编译器&#xff09; 是该版本的一个重要性能特性&#xff0c;首次让 PHP 有了运行时即时编译的能力&#xff0c;从解释型语言迈向了“编译执行”的方向。 什么是 JIT&#xff1f; JIT 是 即时编译&#xff08;Just-In-Time c…...

视觉分析开发范例:Puppeteer截图+计算机视觉动态定位

一、选型背景&#xff1a;传统爬虫已无力应对的视觉挑战 在现代互联网环境中&#xff0c;尤其是小红书、抖音、B站等视觉驱动型平台&#xff0c;传统基于 HTML 的爬虫已经难以满足精准数据采集需求&#xff1a; 内容加载由 JS 动态触发&#xff0c;难以直接解析 HTML&#xf…...

Linux 基础开发工具的使用

目录 前言 一&#xff1a;下载工具yum 二&#xff1a;文本编辑器vim 1. 命令模式 2. 插入模式 3. 底行模式 三&#xff1a;gcc和g 基本使用格式 常用选项及作用 编译过程示例 四、Linux 项目自动化构建工具 ——make/Makefile 1. make 与 Makefile 的关系 2. Make…...

ElasticSearch查询指定时间内出现的次数/2秒内出现的次数

查询指定时间内出现的次数 POST process-log/_search {"size": 0,"query": {"bool": {"filter": [{"range": {"requestTime": {"from": 1722470400000,"to": 1722556800000}}}]}},"agg…...

华为云Flexus+DeepSeek征文 | Dify-LLM平台一键部署教程及问题解决指南

作者简介 我是摘星&#xff0c;一名专注于云计算和AI技术的开发者。本次通过华为云MaaS平台体验DeepSeek系列模型&#xff0c;将实际使用经验分享给大家&#xff0c;希望能帮助开发者快速掌握华为云AI服务的核心能力。 目录 1. 前言 2. 准备工作 2.1 注册华为云账号 2.2 确…...

STP协议:如何消除网络环路风暴

生成树协议&#xff08;STP&#xff0c;Spanning Tree Protocol&#xff09;的主要功能&#xff1a; 消除网络环路导致的广播风暴问题&#xff08;环路会引发MAC地址表不稳定&#xff09;防止网络中的主机接收重复数据帧 STP工作原理&#xff1a; 选举根桥&#xff08;Root …...

哈工大计算机系统2025大作业——Hello的程序人生

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算学部 学   号 2023113072 班 级 23L0513 学 生 董国帅 指 导 教 师 史先俊 计算机科学与…...

物联网常用协议Modbus、CAN、BACnet介绍

一、Modbus Modbus 作为工业通信领域的基石,是一款被广泛应用的工业通信协议,主要用于实现可编程逻辑控制器(PLC)等工业电子设备之间的连接。1979 年,Modicon 公司(现施耐德电气的一部分)开发了这一协议,旨在简化工厂内设备间的通信流程。经过多年发展,Modbus 衍生出…...

Vue中van-stepper与input值不同步问题及解决方案

一、问题描述 在使用Vant UI的van-stepper步进器组件与原生input输入框绑定同一响应式数据时&#xff0c;出现以下现象&#xff1a; 通过步进器修改值后&#xff0c;页面直接输出{{ count }}和watch监听器均能获取最新值但input输入框显示的数值未同步更新&#xff0c;仍为旧…...

react基础技术栈

react基础技术栈 react项目构建react的事件绑定React组件的响应式数据条件渲染和列表循环表单绑定 Props和组件间传值&#xff0c;插槽react中的样式操作 生命周期ref 和 context函数组件和hook高阶组件React性能问题React-route的三个版本react-router使用步骤react-router提供…...

Three.js搭建小米SU7三维汽车实战(4)场景搭建

场地搭建 javascript // 导入threejs import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // 1. 创建场景 const scene new THREE.Scene(); // 2. 创建相机 const camera ne…...

redis五种数据结构底层实现

参考文档&#xff1a; redis5种数据结构底层实现...

Excel 统计某个字符串在指定区域出现的次数

【本文概要】 Excel 统计某个字符串在指定区域出现的次数&#xff1a; 1、Excel 统计一个单元格内的某字符串的出现次数 2、Excel 统计某一列所有单元格内的某字符串的出现次数 3、Excel 统计某一区域所有单元格内的某字符串的出现次数 1、Excel 统计一个单元格内的某字符串的出…...