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

微信小程序 navigateTo 栈超过多层后会失效

背景。自定义导航栏。体验版发布后。产品进行测试。发现底部导航切换多了以后会失效,所有uni.navigateTo都会失效。

  • 真机测试不会报错。不会提示

解决方案:上代码

  • 原理:检测栈的长度。超过了使用reLauch进行跳转便清空了navigateTo的栈空间,再重新继续使用navigateTo。也可以都是用reLauch,但体验度不好,会白屏后加载。
<template><view class="custom-tabbar"><!-- 彩色装饰条 - 按设计稿三色比例 --><view class="color-bars"><view class="color-bar bar-orange"></view><view class="color-bar bar-brown"></view><view class="color-bar bar-red"></view></view><!-- tabBar内容 --><view class="tabbar-content"><!-- 首页 --><view class="tab-item" @click="switchTab('home')" :class="{ 'tab-active': activeTab === 'home' }"><image:src="activeTab === 'home' ? '/static/img/figma/首页.png' : '/static/img/figma/首页1.png'"class="tab-icon":class="{ 'icon-active': activeTab === 'home' }"mode="aspectFit" /><text class="tab-text" :class="{ active: activeTab === 'home' }">首页</text></view><!-- 动态 --><view class="tab-item" @click="switchTab('dynamic')" :class="{ 'tab-active': activeTab === 'dynamic' }"><image:src="activeTab === 'dynamic' ? '/static/img/figma/动态.png' : '/static/img/figma/动态1.png'"class="tab-icon":class="{ 'icon-active': activeTab === 'dynamic' }"mode="aspectFit" /><text class="tab-text" :class="{ active: activeTab === 'dynamic' }">动态</text></view><!-- 项目 --><view class="tab-item" @click="switchTab('project')" :class="{ 'tab-active': activeTab === 'project' }"><image:src="activeTab === 'project' ? '/static/img/figma/项目.png' : '/static/img/figma/项目1.png'"class="tab-icon":class="{ 'icon-active': activeTab === 'project' }"mode="aspectFit" /><text class="tab-text" :class="{ active: activeTab === 'project' }">项目</text></view><!-- 个人中心 --><view class="tab-item" @click="switchTab('profile')" :class="{ 'tab-active': activeTab === 'profile' }"><image:src="activeTab === 'profile' ? '/static/img/figma/个人中心.png' : '/static/img/figma/个人中心1.png'"class="tab-icon":class="{ 'icon-active': activeTab === 'profile' }"mode="aspectFit" /><text class="tab-text" :class="{ active: activeTab === 'profile' }">个人中心</text></view></view><!-- 帮助中心(大logo,不可点击) --><view class="tab-item help-center"><image src="/static/bar/image10.png" class="help-icon" mode="aspectFit" /><text class="help-text">帮助中心</text></view></view>
</template><script>
export default {name: 'CustomTabBar',props: {// 当前激活的tabcurrentTab: {type: String,default: 'home'},// 是否在点击时自动导航。为false时仅切换高亮并抛出事件,不跳转页面navigateOnClick: {type: Boolean,default: true}},data() {return {activeTab: 'home',// 防重复点击,避免连续跳转isNavigating: false,// 页面栈软阈值,超过后改用reLaunch以清栈stackSoftLimit: 8};},watch: {currentTab: {handler(newVal) {this.activeTab = newVal;},immediate: true}},mounted() {// 组件挂载时,根据当前页面路径设置激活状态this.setActiveTabByCurrentPage();},methods: {/*** 切换tab页面* @param {string} tabName - tab名称*/switchTab(tabName) {if (this.activeTab === tabName) {return; // 已经是当前tab,无需切换}// 添加触觉反馈// #ifdef APP-PLUSplus.device.vibrate(50);// #endifthis.activeTab = tabName;// 若关闭自动导航,仅更新激活态并通知父级if (!this.navigateOnClick) {this.$emit('tabChange', tabName);return;}// 计算目标地址let targetUrl = '';switch (tabName) {case 'home':targetUrl = '/pages/index/index';break;case 'dynamic':targetUrl = '/pages/article/index';break;case 'project':targetUrl = '/pages/yzpg/index';break;case 'profile':targetUrl = '/pages/profile/center';break;default:console.warn('未知的tab名称:', tabName);}// 已在目标页则不跳转const pages = getCurrentPages();if (pages.length) {const currentRoute = '/' + pages[pages.length - 1].route;if (currentRoute === targetUrl) {return;}}// 优先使用navigateTo以获得更丝滑的切换;当接近栈上限时自动切换为reLaunch清栈this.navigateToSafe('auto', targetUrl);// 触发父组件事件this.$emit('tabChange', tabName);},/*** 安全导航(带防抖与自动方式)* @param {'auto'|'navigateTo'|'redirectTo'|'reLaunch'|'switchTab'} method* @param {string} url*/navigateToSafe(method, url) {if (this.isNavigating) return;this.isNavigating = true;const release = () => {setTimeout(() => {this.isNavigating = false;}, 300);};try {if (method === 'auto') {const pages = getCurrentPages();const len = pages.length;// 近栈上限走reLaunch,正常走navigateToif (len >= this.stackSoftLimit) {uni.reLaunch({ url, complete: release });} else {uni.navigateTo({ url, complete: release });}} else if (method === 'switchTab') {uni.switchTab({ url, complete: release });} else if (method === 'reLaunch') {uni.reLaunch({ url, complete: release });} else if (method === 'redirectTo') {uni.redirectTo({ url, complete: release });} else {uni.navigateTo({ url, complete: release });}} catch (e) {release();}},/*** 根据当前页面路径设置激活的tab*/setActiveTabByCurrentPage() {const pages = getCurrentPages();if (pages.length === 0) return;const currentPage = pages[pages.length - 1];const currentPath = currentPage.route;// 根据页面路径设置对应的tab状态if (currentPath.includes('pages/index/index')) {this.activeTab = 'home';} else if (currentPath.includes('pages2agree/pages/article/list') ||currentPath.includes('pages/article/index')) {this.activeTab = 'dynamic';} else if (currentPath.includes('pages/yzpg/index')) {this.activeTab = 'project';} else if (currentPath.includes('pages/profile/index') ||currentPath.includes('pages/profile/center') ||currentPath.includes('pages3profile/pages/profile/logged')) {this.activeTab = 'profile';}}}
};
</script><style lang="scss" scoped>
.custom-tabbar {position: fixed;bottom: 0;left: 0;right: 0;z-index: 999;background-color: #ffffff;box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
}/* 彩色装饰条 - 按设计稿样式 */
.color-bars {display: flex;height: 10rpx; /* 按设计稿5px转换为10rpx */background-color: #ffffff;
}.color-bar {height: 100%;
}.bar-orange {background-color: #f2981f; /* 按设计稿颜色 */flex: 350; /* 按设计稿比例 350:248:92 */
}.bar-brown {background-color: #ca5737; /* 按设计稿颜色 */flex: 248; /* 按设计稿比例 */
}.bar-red {background-color: #d84a24; /* 按设计稿颜色 */flex: 92; /* 按设计稿比例 */
}/* tabBar内容 */
.tabbar-content {display: flex;align-items: center;justify-content: space-between;padding: 20rpx 32rpx 26rpx 32rpx; /* 按设计稿调整内边距 */background-color: #ffffff;position: relative; /* 为绝对定位的帮助中心图标提供定位上下文 */padding-right: 160rpx; /* 右侧留出空间给帮助中心大图标 */
}.tab-item {display: flex;flex-direction: column;align-items: center;justify-content: center;flex: 1;position: relative;cursor: pointer;min-width: 0;transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);transform-origin: center;
}.tab-item:active {transform: scale(0.95);
}.tab-item.tab-active {transform: scale(1.05);
}.tab-icon {width: 56rpx; /* 按设计稿28px转换为56rpx */height: 56rpx; /* 按设计稿28px转换为56rpx */margin-bottom: 6rpx; /* 调整图标与文字间距 */transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);filter: grayscale(0);
}.tab-icon.icon-active {filter: grayscale(0) brightness(1.1);transform: scale(1.1);
}.tab-icon-uview {margin-bottom: 6rpx; /* 调整u-icon与文字间距 */
}.help-icon {width: 128rpx; /* 按设计稿64px转换为128rpx */height: 128rpx; /* 按设计稿64px转换为128rpx */display: block;object-fit: contain;margin-bottom: 6rpx; /* 与其他图标保持一致的间距 */
}.tab-text {font-size: 24rpx; /* 按设计稿12px转换为24rpx */color: #393939; /* 按设计稿未选中颜色 */line-height: 1;transition: color 0.3s ease;letter-spacing: 0.96rpx; /* 按设计稿letterSpacing 0.48转换 */
}.tab-text.active {color: #e63e0d; /* 按设计稿选中状态颜色 */font-weight: 600; /* 选中状态稍微加粗 */transform: scale(1.05);
}/* 帮助中心特殊样式 - 按设计稿64x64大图标 */
.help-center {position: absolute;right: 32rpx; /* 按设计稿调整距离右边缘的距离 */bottom: 26rpx; /* 与其他tab项对齐 */width: 128rpx; /* 按设计稿64px转换为128rpx */height: 156rpx; /* 为文字留出足够空间 */z-index: 15; /* 确保在最上层 */display: flex;flex-direction: column; /* 垂直排列 */align-items: center;justify-content: flex-start; /* 从顶部开始排列 */
}.help-center .help-icon {position: relative;z-index: 10;opacity: 1;visibility: visible;
}/* 帮助中心文字样式 */
.help-text {font-size: 24rpx; /* 与其他文字保持一致 */color: #393939; /* 与其他未选中文字保持一致 */line-height: 1;text-align: center;white-space: nowrap;letter-spacing: 0.96rpx; /* 与其他文字保持一致 */
}/* 响应式适配 */
@media screen and (max-width: 750rpx) {.tab-text,.help-text {font-size: 20rpx; /* 小屏幕下稍微缩小字体 */}.tab-icon {width: 48rpx; /* 小屏幕下稍微缩小图标 */height: 48rpx;}.tab-icon-uview {margin-bottom: 4rpx; /* 小屏幕下调整间距 */}/* 小屏幕下调整u-icon大小 */.tab-item .tab-icon-uview /deep/ .u-icon {font-size: 48rpx !important; /* 小屏幕下图标大小 */}.help-center {width: 112rpx; /* 小屏幕下帮助中心图标容器 */height: 140rpx; /* 小屏幕下高度 */right: 24rpx; /* 小屏幕下距离边缘 */}.help-icon {width: 112rpx; /* 小屏幕下帮助中心图标 */height: 112rpx;}.tabbar-content {padding: 16rpx 24rpx 20rpx 24rpx; /* 小屏幕下调整内边距 */padding-right: 140rpx; /* 小屏幕下右侧空间 */}.color-bars {height: 8rpx; /* 小屏幕下装饰条稍微细一些 */}
}/* 安全区域适配 */
@supports (padding-bottom: env(safe-area-inset-bottom)) {.tabbar-content {padding-bottom: calc(26rpx + env(safe-area-inset-bottom));}
}
</style>
http://www.dtcms.com/a/363396.html

相关文章:

  • 【开题答辩全过程】以 基于微信小程序的体育场馆预约管理系统为例,包含答辩的问题和答案
  • 【Git】一文详解Git Rebase和Merge区别 看完必会
  • 整体认识K8s之PriorityClass优先级调度/HPA自动扩缩容机制
  • golang 依赖管理
  • 网络技术名词 CDN NAT GA DNS
  • 深度学习篇---Pytorch常用优化器
  • 力扣72:编辑距离
  • 用 PyTorch 实现食品图像分类:从数据预处理到模型训练与预测
  • mayfly-go:web 版 linux、数据库等管理平台
  • 码农必备!本地调试神器act,GitHub Actions最佳拍档
  • C++ 条件变量,互斥锁
  • vue飞自在酒店管理系统(代码+数据库+LW)
  • 第十七讲:编译链接与函数栈帧
  • Python图像处理模块介绍
  • Linux 文本处理四剑客:cut, sort, uniq, tr
  • springboot redisson 分布式锁切面入门与实战
  • HTML应用指南:利用POST请求获取全国便利蜂门店位置信息
  • 面试tips--JVM(4)--Minor GC Major GC Full GC
  • 从理念到实践:三层解耦架构与“无系统”论
  • 59.螺旋矩阵II
  • 科研界“外挂”诞生了:科学多模态模型Intern-S1-mini开源
  • linux开发板(rk3568,树莓派)自动连接保存好的WIFI
  • 百度网盘基于Flink的实时计算实践
  • SpringMVC —— Spring集成web环境和SpringMVC快速入门
  • 微信小程序列表之分页、刷新、加载更多开发
  • [密码学实战]逆向工程常见工具合集及下载地址(四十七)
  • 顶级天才会思考什么问题
  • Unity切换平台资源重新编译缓慢
  • 嵌入式git分支管理策略
  • 江协科技STM32学习笔记补充之002 对比介绍 I²C 和 SPI 两种常见的串行总线接口