fix(diy-bottom-nav): 优化底部导航栏高亮逻辑,修复分包场景下的激活判断问题

1. 新增decodeEntity工具函数处理URL实体编码
2. 新增packageEntryTab状态追踪分包入口Tab
3. 重构checkTabBarActive方法,支持动态tabBar配置和分包场景判断
4. 优化路由更新和跳转逻辑,适配多分包页面的导航高亮
This commit is contained in:
2026-05-30 11:59:26 +08:00
parent f836254381
commit 6410257a25
2 changed files with 107 additions and 28 deletions

View File

@@ -115,29 +115,83 @@ export const adaptSubpackageUrl = (url) => {
* 检查tabBar是否激活
* @param {string} linkUrl 链接路径 /pages/goods/category
* @param {string} currentPageRoute 当前页面路径 /pages_goods/category
* @param {Object} tabBarList tabBar配置对象,用于动态判断
* @param {Object} packageEntryTab 追踪每个分包的入口Tab { 'pages_goods': '/pages_goods/category' }
* @returns {boolean} 是否激活
*/
export const checkTabBarActive = (linkUrl, currentPageRoute) => {
const linkUrlParts = adaptSubpackageUrl(linkUrl).split('/');
const currentPageRouteParts = currentPageRoute.split('/');
export const checkTabBarActive = (linkUrl, currentPageRoute, tabBarList, packageEntryTab) => {
const adaptedLinkUrl = adaptSubpackageUrl(linkUrl);
const adaptedCurrentRoute = adaptSubpackageUrl(currentPageRoute);
// console.log('diy-bottom-nav verify:', { linkUrlParts, currentPageRouteParts});
// 去除查询参数,仅比较路径部分
const cleanLinkUrl = adaptedLinkUrl.split('?')[0];
const cleanCurrentRoute = adaptedCurrentRoute.split('?')[0];
try {
// 二级页面
if (linkUrlParts[2] === currentPageRouteParts[2]) {
return true;
}
const linkUrlParts = cleanLinkUrl.split('/');
const currentPageRouteParts = cleanCurrentRoute.split('/');
// 一级页面,限定只能是goods相关
if (linkUrlParts[1] === currentPageRouteParts[1] && linkUrlParts[1] === 'pages_goods') {
return true;
}
} catch (error) {
console.error('diy-bottom-nav verify error:', error);
// 首先尝试精确匹配(整个路径匹配)
if (cleanLinkUrl === cleanCurrentRoute) {
return true;
}
return false;
// 如果没有精确匹配,且传入了 tabBarList,使用动态判断逻辑
if (tabBarList && tabBarList.list && Array.isArray(tabBarList.list)) {
// 获取所有 tab 项的链接(去除查询参数)
const tabUrls = tabBarList.list
.filter(item => item.link && item.link.wap_url)
.map(item => adaptSubpackageUrl(item.link.wap_url).split('?')[0]);
// 检查当前 linkUrl 是否是合法的 tab URL
if (!tabUrls.includes(cleanLinkUrl)) {
return false;
}
// 获取当前页面所属的分包名(parts[1])
const currentPackageName = currentPageRouteParts[1];
const linkPackageName = linkUrlParts[1];
// 如果 linkUrl 和当前页面不在同一个分包,直接返回 false
if (linkPackageName !== currentPackageName) {
return false;
}
// 获取当前页面路径的二级目录(parts[2])
const currentPageSecondPart = currentPageRouteParts[2];
// 检查当前页面路径是否匹配某个 tab 的精确路径
const currentMatchingTab = tabUrls.find(url => {
if (!url) return false;
const parts = url.split('/');
return parts[2] === currentPageSecondPart;
});
// 如果当前页面能精确匹配到某个 tab,那么只有该 tab 高亮
if (currentMatchingTab) {
return cleanLinkUrl === currentMatchingTab;
}
// 当前页面不是任何 tab 的精确匹配(是子页面)
// 使用 packageEntryTab 来确定应该高亮的 tab
if (packageEntryTab && typeof packageEntryTab === 'object') {
const entryTab = packageEntryTab[currentPackageName];
if (entryTab) {
const entryTabParts = entryTab.split('/');
return linkUrlParts[2] === entryTabParts[2];
}
}
// 基于二级路径匹配(fallback)
try {
if (linkUrlParts[2] === currentPageSecondPart) {
return true;
}
} catch (error) {
console.error('diy-bottom-nav verify error:', error);
}
return false;
}
}
export default {

View File

@@ -59,7 +59,7 @@
</template>
<script>
import { adaptSubpackageUrl, checkTabBarActive } from '@/common/js/util.js'
import { adaptSubpackageUrl, checkTabBarActive, decodeEntity } from '@/common/js/util.js'
import DiyMinx from './minx.js'
// 底部导航栏
export default {
@@ -79,7 +79,8 @@ export default {
lang: uni.getStorageSync("lang"),
currentRoute: '', //当前页面路径
jumpFlag: true, //是否可以跳转,防止重复点击
cartAnimation: {}
cartAnimation: {},
packageEntryTab: {} // 追踪每个分包的入口Tab { 'pages_goods': '/pages_goods/category' }
};
},
mounted() {
@@ -130,31 +131,55 @@ export default {
updateCurrentRoute() {
let currentPage = getCurrentPages()[getCurrentPages().length - 1];
if (currentPage && currentPage.route) {
this.currentRoute = currentPage.route;
const newRoute = currentPage.route;
const newRouteParts = newRoute.split('/');
if (this.tabBarList && this.tabBarList.list) {
const tabUrls = this.tabBarList.list
.filter(item => item.link && item.link.wap_url)
.map(item => adaptSubpackageUrl(item.link.wap_url));
for (const tabUrl of tabUrls) {
const tabParts = tabUrl.split('/');
if (tabParts[2] === newRouteParts[2] && tabParts[1] === newRouteParts[1]) {
this.packageEntryTab[newRouteParts[1]] = tabUrl;
break;
}
}
}
this.currentRoute = newRoute;
}
},
redirectTo(link) {
this.$emit('callback');
if (link && link.wap_url) {
const decodedUrl = decodeEntity(link.wap_url);
const adaptedUrl = adaptSubpackageUrl(decodedUrl);
const urlParts = adaptedUrl.split('/');
if (urlParts.length >= 2 && urlParts[1]) {
this.packageEntryTab[urlParts[1]] = adaptedUrl;
}
}
this.$util.diyRedirectTo(link);
},
verify(link) {
if (link == null || link == '' || !link.wap_url) return false;
// 标准化路径格式,确保比较的一致性
let currentPageRoute = this.currentRoute ? '/' + this.currentRoute : '';
let currentPages = getCurrentPages();
let currentPage = currentPages[currentPages.length - 1];
let currentPageRoute = currentPage && currentPage.route ? '/' + currentPage.route : '';
let linkUrl = link.wap_url;
// 首页特殊处理
if (linkUrl === this.$util.INDEX_PAGE_URL && this.name === 'DIY_VIEW_INDEX') {
return true;
}
// 精确匹配当前路径
if (adaptSubpackageUrl(linkUrl) === currentPageRoute) {
return true;
}
return checkTabBarActive(linkUrl, currentPageRoute);
// 使用通用的 checkTabBarActive 函数来判断 tab 高亮状态
return checkTabBarActive(linkUrl, currentPageRoute, this.tabBarList, this.packageEntryTab);
}
}
};