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. 保持原生导航栏流畅体验 ✅

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/83046.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/83046.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/83046.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java大师成长计划之第35天:未来展望与个人总结

引言 作为一门历史悠久的编程语言&#xff0c;Java自1995年问世以来&#xff0c;经历了多个版本的迭代与演进&#xff0c;依然在当今技术生态中占据着重要地位。从早期的Java SE、Java EE到后来的Java Spring框架&#xff0c;再到现代的微服务架构与云原生应用&#xff0c;Jav…

Ubuntu开机自动运行Docker容器中的Qt UI程序

Ubuntu开机自动运行Docker容器中的Qt UI程序 引言为什么需要这样配置?解决方案概览详细实现步骤1. 创建容器启动脚本2. 创建系统服务3. 配置自动登录和显示设置常见问题解决方案1. 程序无法显示(X11权限问题)2. 分辨率设置不生效3. 服务启动失败安全注意事项结语附录:完整文…

Scratch节日 | 龙舟比赛 | 端午节

端午节快乐&#xff01; 这款专为孩子们打造的Scratch游戏——《龙舟比赛》&#xff0c;让你在掌控龙舟的竞速中&#xff0c;沉浸式体验中华传统节日的魅力&#xff01; &#x1f3ae; 游戏亮点 节日氛围浓厚&#xff1a;化身龙舟选手&#xff0c;在波涛汹涌的河流中展开刺激竞…

(五)MMA(OpenTelemetry/Rabbit MQ/ApiGateway/MongoDB)

文章目录 项目地址一、OpenTelemetry1.1 配置OpenTelemetry1. 服务添加2. 添加服务标识3. 添加请求的标识4. 添加中间价 二、Rabbit MQ2.1 配置Rabbit MQ1. docker-compose2. 添加Rabbit MQ的Connect String 2.2 替换成Rabbit MQ1. 安装所需要的包2. 使用 三、API Gateways3.1 …

格恩朗超声波水表 助力农业精准灌溉与振兴​

在农业现代化的征程中&#xff0c;水资源的精准利用至关重要&#xff0c;而这离不开高精度计量设备的支持。大连格恩朗品牌积极响应国家全面推进乡村振兴、加快农业农村现代化的号召&#xff0c;精心打造的超声波水表&#xff0c;凭借其超高精度&#xff0c;成为绿色灌溉领域的…

微信小程序页面嵌套web-view点击系统导航返回时进行弹窗处理

实现效果&#xff1a;微信小程序页面嵌套web-view点击系统导航返回时进行弹窗处理 首先在web-view里是不可实现的&#xff08;据我了解下来&#xff09; 参考小程序文档&#xff1a;page-container 大致逻辑&#xff1a; 1、page-container可实现页面离开前拦截 2、由于web-vie…

设计模式25——中介者模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 中介者模式&#xff08;Mediat…

Java基础 Day25

一、线程通信 1、简介 确保线程能够按照预定的顺序执行并且能够安全地访问共享资源 使多条线程更好的进行协同工作 2、常用方法 void wait() 使当前线程进入等待状态 void notify(); 随机唤醒单个等待的线程&#xff08;可以空唤醒&#xff09; void notifyAll(); 唤醒…

WebSocket与实时对话式AI服务的集成

WebSocket与实时对话式AI服务的集成 在现代对话式AI系统中,传统的HTTP请求-响应模型已难以满足实时交互的体验需求。特别是用户对响应速度、逐字输出、会话上下文保持等方面提出更高要求时,需要一种能够建立持久连接并支持双向通信的协议。WebSocket正是在这一背景下,成为A…

iOS 集成网易云信IM

云信官方文档在这 看官方文档的时候&#xff0c;版本选择最新的V10。 1、CocoPods集成 pod NIMSDK_LITE 2、AppDelegate.m添加头文件 #import <NIMSDK/NIMSDK.h> 3、初始化 NIMSDKOption *mrnn_option [NIMSDKOption optionWithAppKey:"6f6568e354026d2d658a…

人工智能100问☞第37问:什么是扩散模型?

目录 ​​一、通俗解释 二、专业解析​​ 三、权威参考 扩散模型是一种​​通过系统性地添加再去除噪声来生成新数据(如图像)的生成式AI技术​​,其核心机制分为两个阶段:正向扩散​​:对原始数据(如清晰图片)逐步添加噪声,直至完全变成随机噪点(类似老照片逐渐模糊…

传输层核心技术解析

目录 一、端口号机制 二、网络诊断工具 1. netstat命令 2. pidof工具 三、UDP协议详解 协议特征 典型应用场景 四、TCP协议深度解析 核心机制 状态转换模型 特殊状态说明 五、协议对比分析 六、开发实践要点 一、端口号机制 核心作用&#xff1a;标识主机唯一进程…

IO Vs NIO

一、IO(传统阻塞式) 全称‌&#xff1a;Input/Output(输入/输出) 定义‌&#xff1a;Java 1.0 引入的基础 I/O 模型&#xff0c;基于流&#xff08;Stream&#xff09;的同步阻塞操作&#xff0c;线程在读写数据时会阻塞直到操作完成。 二、NIO(新式非阻塞式) ‌全…

基于原生JavaScript前端和 Flask 后端的Todo 应用

Demo地址&#xff1a;https://gitcode.com/rmbnetlife/todo-app-js-flask.git Python Todo 应用 这是一个使用Python Flask框架开发的简单待办事项(Todo)应用&#xff0c;采用前后端分离架构。本项目实现了待办事项的添加、删除、状态切换等基本功能&#xff0c;并提供了直观…

005 ElasticSearch 许可证过期问题

ElasticSearch 许可证过期问题 项目启动报错 org.elasticsearch.client.ResponseException: method [GET], host [http://127.0.0.1:9200], URI [/_cluster/health/], status line [HTTP/1.1 403 Forbidden] {"error":{"root_cause":[{"type":…

哪些岗位最易被AI替代?

随着AI技术高速演进&#xff0c;一场“职场大洗牌”正悄然上演。当ChatGPT出口成章、机器人能精准执勤&#xff0c;AI时代的“就业焦虑”已不再是空谈。你是否认真思考过&#xff0c;自己所处的岗位是否也正面临被AI边缘化的风险&#xff1f; 以下几类职业&#xff0c;已成为AI…

信号槽中 sender() 的作用

好的,sender() 是 Qt 框架中的一个重要函数,它用于获取触发当前槽函数的对象。在 Qt 的信号和槽机制中,一个信号可以连接到多个槽函数,而一个槽函数也可以被多个信号触发。sender() 函数允许你在槽函数中确定是哪个对象触发了当前信号。 信号和槽机制 在 Qt 中,信号和槽…

深度学习|pytorch基本运算

【1】引言 pytorch是深度学习常用的包&#xff0c;顾名思义&#xff0c;就是python适用的torch包&#xff0c;在python里面使用时直接import torch就可以调用。 需要注意的是&#xff0c;pytorch包与电脑配置、python版本有很大关系&#xff0c;一定要仔细阅读安装要求、找到…

DeepSeek 赋能数字人直播带货:技术革新重塑电商营销新生态

目录 一、引言二、DeepSeek 技术探秘2.1 DeepSeek 技术原理剖析2.2 DeepSeek 与其他大模型对比优势 三、数字人直播带货现状洞察3.1 数字人直播带货发展历程回顾3.2 市场规模与增长趋势分析3.3 现存问题与挑战探讨 四、DeepSeek 在数字人直播带货中的应用实例4.1 交个朋友的成功…

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.11 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.11 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图。 dataframe<-data.frame( densityc(570,565,…