refactor:调整Tabbar组件渲染逻辑,动态渲染

master
黄伟杰 3 weeks ago
parent 085fa5b297
commit 470aeac6c4

@ -18,7 +18,7 @@
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import useUserStore from '@/store/modules/user'
import { storeToRefs } from 'pinia'
import { getDynamicTabMenus } from '@/utils/permissionMenu'
import { getTabBarMenus } from '@/utils/permissionMenu'
import { useI18n } from 'vue-i18n'
const TABBAR_VISIBILITY_EVENT = 'tabbar-visibility-change'
@ -42,44 +42,72 @@ const workSelectedIcon = '/static/images/tabbar/work_.png'
const mineIcon = '/static/images/tabbar/mine.png'
const mineSelectedIcon = '/static/images/tabbar/mine_.png'
const routeMap = {
'pages/index': 0,
'pages/report': 1,
'pages/work': 2,
'pages/mine': 3
const dynamicTabIconList = [
{
icon: homeIcon,
selectedIcon: homeSelectedIcon
},
{
icon: reportIcon,
selectedIcon: reportSelectedIcon
},
{
icon: workIcon,
selectedIcon: workSelectedIcon
}
]
function normalizeRoute(path = '') {
return String(path || '').trim().replace(/^\/+/, '')
}
function resolveTabIcons(path, index) {
const route = normalizeRoute(path)
if (route === 'pages/index') {
return {
icon: homeIcon,
selectedIcon: homeSelectedIcon
}
}
if (route === 'pages/report') {
return {
icon: reportIcon,
selectedIcon: reportSelectedIcon
}
}
if (route === 'pages/work') {
return {
icon: workIcon,
selectedIcon: workSelectedIcon
}
}
return dynamicTabIconList[index % dynamicTabIconList.length]
}
function getCurrentActiveIndex() {
const pages = getCurrentPages()
if (pages && pages.length > 0) {
const route = pages[pages.length - 1].route
return routeMap[route] !== undefined ? routeMap[route] : 0
const currentIndex = tabList.value.findIndex((item) => normalizeRoute(item.path) === route)
return currentIndex >= 0 ? currentIndex : 0
}
return 0
}
const tabList = computed(() => {
const dynamicMenus = getDynamicTabMenus(menus.value)
const dynamicTabList = getTabBarMenus(menus.value)
.map((menu, index) => {
const icons = resolveTabIcons(menu.path, index)
return {
text: String(menu.name || menu.enName || '').trim() || `菜单${index + 1}`,
icon: icons.icon,
selectedIcon: icons.selectedIcon,
path: menu.path
}
})
return [
{
text: t('nav.home'),
icon: homeIcon,
selectedIcon: homeSelectedIcon,
path: '/pages/index'
},
{
text: dynamicMenus[0]?.name || t('tab.report'),
icon: reportIcon,
selectedIcon: reportSelectedIcon,
path: '/pages/report'
},
{
text: dynamicMenus[1]?.name || dynamicMenus[0]?.name || t('tab.work'),
icon: workIcon,
selectedIcon: workSelectedIcon,
path: '/pages/work'
},
...dynamicTabList,
{
text: t('nav.mine'),
icon: mineIcon,

@ -53,6 +53,7 @@ import { ref } from "vue";
import config from '@/config.js'
import useUserStore from '@/store/modules/user'
import NavBar from '@/components/common/NavBar.vue'
import { getFirstTabBarPath } from '@/utils/permissionMenu'
const userStore = useUserStore()
const codeUrl = ref("");
@ -106,8 +107,9 @@ async function pwdLogin() {
function loginSuccess(result) {
userStore.getInfo().then(res => {
const targetPath = getFirstTabBarPath(res?.data?.menus)
uni.reLaunch({
url: '/pages/index'
url: targetPath
});
})
}

@ -161,6 +161,26 @@ export function buildNavMenuViewModels(menus) {
})
}
export function getTabBarMenus(menus) {
return getTopLevelMenus(menus)
.filter((menu) => menu && menu.visible !== false)
.map((menu) => {
const path = resolveMenuUrl(menu)
if (!path) {
return null
}
return {
...menu,
path
}
})
.filter(Boolean)
}
export function getFirstTabBarPath(menus, fallback = '/pages/mine') {
return getTabBarMenus(menus)[0]?.path || fallback
}
export function getDynamicTabMenus(menus) {
return getTopLevelMenus(menus).filter((menu) => !looksLikeHomeMenu(menu))
}

Loading…
Cancel
Save