20260806173205
This commit is contained in:
1 parent
74cdb7f306
commit
6baa339efa
14 files changed
+804
-324
No files matched your search
@@ -1,17 +1,7 @@
|
||||
<script setup>
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
ArrowLeft,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
House,
|
||||
Maximize2,
|
||||
Minimize2,
|
||||
RotateCw,
|
||||
X,
|
||||
} from "@lucide/vue";
|
||||
import { theme } from "antdv-next";
|
||||
import { ChevronLeft, ChevronRight, X } from "@lucide/vue";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { usePermissionStore } from "@/stores/permissions";
|
||||
|
||||
@@ -19,7 +9,6 @@ const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
const { token } = theme.useToken();
|
||||
const headerRef = ref(null);
|
||||
const trackRef = ref(null);
|
||||
const overflowed = ref(false);
|
||||
@@ -161,62 +150,15 @@ function handleTabKeydown(event, index) {
|
||||
focusAdjacentTab(index, event.key === "ArrowLeft" ? -1 : 1);
|
||||
}
|
||||
|
||||
function goConsole() {
|
||||
router.push("/dashboard");
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
router.back();
|
||||
}
|
||||
|
||||
function refreshCurrentRoute() {
|
||||
appStore.refreshRoute(route.fullPath);
|
||||
}
|
||||
|
||||
function toggleMaximize() {
|
||||
appStore.toggleContentMaximized();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header
|
||||
ref="headerRef"
|
||||
class="tab-header"
|
||||
:style="{
|
||||
'--tabs-active-bg': token.colorPrimaryBg,
|
||||
'--tabs-active-color': token.colorPrimary,
|
||||
'--tabs-idle-bg': token.colorFillQuaternary,
|
||||
}"
|
||||
>
|
||||
<div class="tab-actions">
|
||||
<a-tooltip title="返回上一页" placement="bottom">
|
||||
<button type="button" class="tab-action" aria-label="返回上一页" @click="goBack">
|
||||
<ArrowLeft />
|
||||
</button>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip title="刷新当前页" placement="bottom">
|
||||
<button
|
||||
type="button"
|
||||
class="tab-action"
|
||||
aria-label="刷新当前页"
|
||||
@click="refreshCurrentRoute"
|
||||
>
|
||||
<RotateCw />
|
||||
</button>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip title="返回控制台" placement="bottom">
|
||||
<button type="button" class="tab-action" aria-label="返回控制台" @click="goConsole">
|
||||
<House />
|
||||
</button>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
<header ref="headerRef" class="tab-header">
|
||||
<!-- 滚动按钮 -->
|
||||
<button
|
||||
v-if="overflowed"
|
||||
type="button"
|
||||
class="tab-nav-button"
|
||||
class="tab-btn"
|
||||
aria-label="向左滚动页签"
|
||||
:disabled="!canScrollLeft"
|
||||
@click="scrollTabs(-1)"
|
||||
@@ -224,6 +166,7 @@ function toggleMaximize() {
|
||||
<ChevronLeft />
|
||||
</button>
|
||||
|
||||
<!-- 标签轨道 -->
|
||||
<div ref="trackRef" class="tab-track" role="tablist" @scroll.passive="updateScrollState">
|
||||
<div
|
||||
v-for="(item, index) in tabItems"
|
||||
@@ -258,28 +201,13 @@ function toggleMaximize() {
|
||||
<button
|
||||
v-if="overflowed"
|
||||
type="button"
|
||||
class="tab-nav-button"
|
||||
class="tab-btn"
|
||||
aria-label="向右滚动页签"
|
||||
:disabled="!canScrollRight"
|
||||
@click="scrollTabs(1)"
|
||||
>
|
||||
<ChevronRight />
|
||||
</button>
|
||||
|
||||
<a-tooltip
|
||||
:title="appStore.contentMaximized ? '退出最大化' : '应用内最大化'"
|
||||
placement="bottom"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="tab-nav-button tab-maximize"
|
||||
aria-label="应用内最大化"
|
||||
@click="toggleMaximize"
|
||||
>
|
||||
<Minimize2 v-if="appStore.contentMaximized" />
|
||||
<Maximize2 v-else />
|
||||
</button>
|
||||
</a-tooltip>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
@@ -292,16 +220,53 @@ function toggleMaximize() {
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 3px 8px;
|
||||
background: var(--fms-surface);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* ---- 通用小按钮 ---- */
|
||||
.tab-btn {
|
||||
display: grid;
|
||||
flex: none;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
color: #71717a;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
color 0.15s ease,
|
||||
background-color 0.15s ease;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
color: #3f3f46;
|
||||
background: #f4f4f5;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
.lucide {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
stroke-width: 1.8;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- 标签轨道 ---- */
|
||||
.tab-track {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
gap: 6px;
|
||||
padding: 2px 0;
|
||||
margin: -2px 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-y: visible;
|
||||
overscroll-behavior-inline: contain;
|
||||
scrollbar-width: none;
|
||||
|
||||
@@ -310,6 +275,7 @@ function toggleMaximize() {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- 标签项 ---- */
|
||||
.tab-item {
|
||||
display: flex;
|
||||
flex: none;
|
||||
@@ -317,17 +283,28 @@ function toggleMaximize() {
|
||||
height: 28px;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
background: var(--tabs-idle-bg);
|
||||
color: var(--fms-text-secondary);
|
||||
border-radius: 6px;
|
||||
background: #f4f4f5;
|
||||
color: #71717a;
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
color 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
color: var(--tabs-active-color);
|
||||
background: #f4f4f5;
|
||||
color: #3f3f46;
|
||||
}
|
||||
|
||||
&--active {
|
||||
background: var(--tabs-active-bg);
|
||||
color: var(--tabs-active-color);
|
||||
background: #f4f4f5;
|
||||
color: #3f3f46;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 1px 3px rgb(0 0 0 / 6%), 0 1px 2px rgb(0 0 0 / 4%);
|
||||
|
||||
&:hover {
|
||||
background: #f4f4f5;
|
||||
color: #3f3f46;
|
||||
}
|
||||
}
|
||||
|
||||
&__select,
|
||||
@@ -345,8 +322,8 @@ function toggleMaximize() {
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 7px;
|
||||
font-size: 12px;
|
||||
padding: 0 8px;
|
||||
font-size: 13px;
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
@@ -359,6 +336,7 @@ function toggleMaximize() {
|
||||
flex: none;
|
||||
padding: 0;
|
||||
place-items: center;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgb(0 0 0 / 6%);
|
||||
@@ -367,70 +345,8 @@ function toggleMaximize() {
|
||||
.lucide {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
stroke-width: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-nav-button {
|
||||
display: grid;
|
||||
flex: none;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
color: var(--fms-text-secondary);
|
||||
background: var(--tabs-idle-bg);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
color: var(--tabs-active-color);
|
||||
background: var(--tabs-active-bg);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
.lucide {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-actions {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tab-action {
|
||||
display: grid;
|
||||
flex: none;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
color: var(--fms-text-secondary);
|
||||
background: var(--tabs-idle-bg);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
color 0.15s ease,
|
||||
background-color 0.15s ease;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
color: var(--tabs-active-color);
|
||||
background: var(--tabs-active-bg);
|
||||
}
|
||||
|
||||
.lucide {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user