support iOS 26 navbar

This commit is contained in:
Timi
2026-08-29 23:40:26 +08:00
parent aac6989728
commit d0914fa683
4 changed files with 516 additions and 173 deletions
+7 -173
View File
@@ -1,57 +1,6 @@
<template>
<div class="main-layout">
<t-navbar
ref="navBarRef"
v-if="navBarStore.isShowing"
class="nav-bar"
:left-arrow="!!navBarStore.canBack"
:z-index="20"
@left-click="doBack"
>
<template #title>
<div id="app-nav-title" class="nav-title-slot">
<span v-if="!navBarStore.customTitleVisible" class="nav-title-text" v-text="navBarStore.title" />
</div>
</template>
<template v-if="navBarStore.customRightVisible || navBarStore.rightIcon || navBarStore.rightText" #right>
<div class="nav-right-slot">
<div v-if="navBarStore.customRightVisible" id="app-nav-right" />
<t-badge
v-else-if="navBarStore.rightIcon && navBarStore.rightBadge !== undefined"
class="badge"
:count="navBarStore.rightBadge"
:max-count="99"
:show-zero="false"
>
<button
class="nav-btn"
type="button"
:disabled="navBarStore.rightDisabled"
@click="!navBarStore.rightDisabled && navBarStore.rightAction?.()"
>
<t-icon :name="navBarStore.rightIcon" size="1.25rem" />
</button>
</t-badge>
<button
v-else-if="navBarStore.rightIcon"
class="nav-btn"
type="button"
:disabled="navBarStore.rightDisabled"
@click="!navBarStore.rightDisabled && navBarStore.rightAction?.()"
>
<t-icon :name="navBarStore.rightIcon" size="1.25rem" />
</button>
<span
v-else
v-text="navBarStore.rightText"
class="nav-text"
:style="{ color: navBarStore.rightDisabled ? 'var(--td-text-color-disabled)' : navBarStore.rightTextColor ? navBarStore.rightTextColor : '#333' }"
:class="{ clickable: !!navBarStore.rightAction && !navBarStore.rightDisabled, disabled: navBarStore.rightDisabled }"
@click="!navBarStore.rightDisabled && navBarStore.rightAction?.()"
></span>
</div>
</template>
</t-navbar>
<app-nav-bar @height-change="onChangeNavBarHeight" />
<div class="router-view">
<page-transition />
</div>
@@ -77,63 +26,24 @@
</template>
<script setup lang="ts">
import AppNavBar from "@/components/navbar/index.vue";
import PageTransition from "@/components/PageTransition.vue";
import {useNavBarStore} from "@/store/navBarStore";
import {useTabBarStore} from "@/store/tabBarStore";
import { permissionCodes } from "@/utils/permission";
import { useUserStore } from "timi-web-api";
const route = useRoute();
const router = useRouter();
const navBarStore = useNavBarStore();
const tabBarStore = useTabBarStore();
const userStore = useUserStore();
// ---------- 导航高度 ----------
const navBarRef = ref();
let navBarResizeObs: ResizeObserver | undefined;
onMounted(() => {
if (!navBarRef.value) {
return;
}
navBarResizeObs = new ResizeObserver((entries) => {
for (const entry of entries) {
navBarStore.setHeight(entry.contentRect.height);
return;
}
});
navBarResizeObs.observe(navBarRef.value.$el.querySelector(".t-navbar__content"));
});
onUnmounted(() => {
if (navBarResizeObs) {
navBarResizeObs.disconnect();
}
});
// ---------- 导航返回 ----------
function doBack(): void {
if (navBarStore.backTo) {
router.push(navBarStore.backTo);
navBarStore.setBackTo(undefined);
return;
}
router.back();
}
// ---------- 导航边距 ----------
const navBarHeight = computed(() => {
if (navBarStore.isShowing) {
return "48px";
}
return "0px";
});
const navBarHeight = ref("0px");
function onChangeNavBarHeight(value: string): void {
navBarHeight.value = value;
}
// ---------- Tab 切换 ----------
@@ -236,82 +146,6 @@ const tabBarHeight = computed(() => {
height: 100%;
transition: padding-bottom .24s ease;
.nav-bar {
:deep(.t-navbar__content) {
color: var(--tui-black, #000);
overflow: visible;
box-shadow: 0 3px 8px rgba(0, 0, 0, .1);
background: rgba(250, 250, 250, .8);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.badge {
:deep(.t-badge__content) {
display: flex;
align-items: center;
}
}
.nav-btn {
padding: 0;
border: none;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--td-text-color-primary, #333);
background: transparent;
&:disabled {
color: var(--td-text-color-disabled);
cursor: not-allowed;
}
}
.nav-title-slot {
min-width: 0;
}
.nav-title-text {
overflow: hidden;
display: block;
white-space: nowrap;
text-overflow: ellipsis;
}
.nav-right-slot {
width: 6rem;
height: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
:deep(.t-badge) {
display: inline-flex;
}
}
.nav-text {
cursor: default;
&.clickable {
cursor: pointer;
}
&.disabled {
cursor: not-allowed;
}
}
}
:deep(.t-navbar__right),
:deep(.t-navbar__right-content) {
overflow: visible;
}
.router-view {
height: 100%;
}