This commit is contained in:
itcsx committed 2026-09-05 23:08:56 +08:00
1 parent 6d68eb11b7
commit 67c632715b
29 files changed
+2801 -739

No files matched your search

+179
View File
@@ -0,0 +1,179 @@
<template>
<div class="toolbar">
<div class="toolbar-left">
<a-tooltip title="返回顶层">
<a-button
type="text"
class="nav-btn"
:disabled="!canGoTop"
@click="$emit('go-top')"
>
<HomeOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="返回上层">
<a-button
type="text"
class="nav-btn"
:disabled="!canGoBack"
@click="$emit('go-back')"
>
<ArrowLeftOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="刷新">
<a-button
type="text"
class="nav-btn"
:loading="loading"
@click="$emit('refresh')"
>
<ReloadOutlined />
</a-button>
</a-tooltip>
</div>
<div class="toolbar-center">
<a-breadcrumb class="breadcrumb">
<a-breadcrumb-item
v-for="(item, index) in breadcrumbItems"
:key="index"
@click="onBreadcrumbClick(item, index)"
:class="{ clickable: index < breadcrumbItems.length - 1 }"
>
<template v-if="index === 0">
<LaptopOutlined style="margin-right: 4px" />
</template>
<span :style="{ cursor: index < breadcrumbItems.length - 1 ? 'pointer' : 'default',
color: index < breadcrumbItems.length - 1 ? '#1677ff' : '' }">{{ item.displayName }}</span>
</a-breadcrumb-item>
</a-breadcrumb>
</div>
<div class="toolbar-right">
<a-input-search
v-model:value="searchKeyword"
placeholder="搜索文件名称"
allow-clear
style="width: 240px"
@search="onSearch"
@pressEnter="onSearch"
>
<template #prefix>
<SearchOutlined />
</template>
</a-input-search>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import {
HomeOutlined,
ArrowLeftOutlined,
ReloadOutlined,
LaptopOutlined,
SearchOutlined,
} from "@ant-design/icons-vue";
interface BreadcrumbItem {
value: string;
displayName: string;
}
const props = defineProps<{
pathStack: BreadcrumbItem[];
rootPath: string;
loading: boolean;
}>();
const emit = defineEmits([
"go-top",
"go-back",
"refresh",
"search",
"breadcrumb-click",
]);
const searchKeyword = ref("");
const canGoTop = computed(() => {
return props.pathStack.length > 1;
});
const canGoBack = computed(() => {
return props.pathStack.length > 1;
});
const breadcrumbItems = computed(() => {
return props.pathStack;
});
const onSearch = () => {
emit("search", searchKeyword.value);
};
const onBreadcrumbClick = (item: BreadcrumbItem, index: number) => {
emit("breadcrumb-click", item, index);
};
</script>
<style lang="less">
.toolbar {
display: flex;
align-items: center;
padding: 6px 12px;
background: #fafafa;
border-bottom: 1px solid #e8e8e8;
gap: 12px;
}
.toolbar-left {
display: flex;
gap: 2px;
flex-shrink: 0;
}
.nav-btn {
width: 36px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
}
.nav-btn:hover:not(:disabled) {
background: #e6f4ff;
color: #1677ff;
}
.nav-btn:disabled {
color: #bfbfbf;
}
.toolbar-center {
flex: 1;
overflow: hidden;
}
.breadcrumb {
margin: 0;
font-size: 14px;
}
.breadcrumb-item.clickable {
cursor: pointer;
}
.breadcrumb-item.clickable:hover {
color: #1677ff;
}
.toolbar-right {
flex-shrink: 0;
}
</style>