Files
JoyD/AutoRobot/Windows/Robot/Web/src/DockLayout/TabPage.vue

237 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="tab-page">
<!-- 使用panels数组渲染标签栏 -->
<div v-if="showTabs && panels && panels.length > 0" class="tab-header">
<div
v-for="(panel, index) in panels"
:key="panel.id"
:class="['tab-item', { 'active': activeTabIndex === index }]"
@click="setActiveTab(index)"
>
{{ panel.title }}
<button
class="button-icon p-[2px] rounded hover:opacity-100 opacity-80"
@click.stop="closeTab(panel.id)"
aria-label="关闭"
>
<svg width="11" height="11" viewBox="0 0 11 11" aria-hidden="true">
<line x1="2" y1="2" x2="9" y2="9" stroke="#e6efff" stroke-width="1" />
<line x1="2" y1="9" x2="9" y2="2" stroke="#e6efff" stroke-width="1" />
</svg>
</button>
</div>
<div class="tab-placeholder"></div>
</div>
<!-- Tab页内容区域 -->
<div class="tab-content">
<!-- 渲染slot内容Panel组件 -->
<slot></slot>
</div>
</div>
</template>
<script setup>
import { defineProps, defineEmits, ref } from 'vue'
const props = defineProps({
id: { type: String, required: true },
title: { type: String, default: '标签页' },
// 从父组件传入的面板数组
panels: {
type: Array,
default: () => []
},
// 是否显示页标签栏
showTabs: {
type: Boolean,
default: true
}
})
const emit = defineEmits(['tabChange', 'tabClose', 'tabAdd'])
// 当前激活的标签页索引
const activeTabIndex = ref(props.activeIndex)
// 设置激活的标签页
const setActiveTab = (index) => {
if (index >= 0 && index < props.tabs.length) {
activeTabIndex.value = index
emit('tabChange', { index, tab: props.tabs[index] })
}
}
// 关闭标签页
const closeTab = (tabId) => {
emit('tabClose', { id: tabId })
}
</script>
<style scoped>
.tab-page {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background: #5D6B99;
border: 1px solid #c7d2ea;
border-radius: 0;
overflow: hidden;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
:root {
--vs-blue-top: #4f72b3;
--vs-blue-bottom: #3c5a99;
}
/* 标签栏样式 - 模仿Windows Forms */
.tab-header {
display: flex;
flex-wrap: nowrap;
height: 28px;
background: transparent;
border-bottom: none;
overflow-x: auto;
overflow-y: hidden;
padding-top: 2px;
}
.tab-item {
display: flex;
align-items: center;
justify-content: space-between;
height: 26px;
padding: 0 16px;
margin-left: 1px;
background: linear-gradient(to bottom, var(--vs-blue-top), var(--vs-blue-bottom));
border-bottom-color: #c7d2ea;
border-radius: 3px 3px 0 0;
cursor: pointer;
white-space: nowrap;
color: white;
font-size: 12px;
user-select: none;
}
.tab-item.active {
background: #ffffff;
border: 1px solid #c7d2ea;
border-bottom-color: #ffffff;
border-top-width: 2px;
border-top-color: #0078d7;
color: #333;
font-weight: 500;
}
.tab-item:hover {
background: linear-gradient(to bottom, #5a7db8, #4667a4);
}
.tab-item.active:hover {
background: #ffffff;
color: #333;
}
.button-icon {
margin-left: 8px;
background: transparent;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
/* 确保在活动标签页中的按钮样式正确 */
.tab-item.active .button-icon {
opacity: 0.6;
}
.tab-item.active .button-icon:hover {
opacity: 1;
background: #f3f4f6;
}
/* 确保在非活动标签页中的按钮样式正确 */
.tab-item:not(.active) .button-icon svg line {
stroke: #e6efff;
}
.tab-item:not(.active) .button-icon:hover svg line {
stroke: white;
}
.tab-placeholder {
background: transparent;
border: transparent;
border-bottom-color: #c7d2ea;
}
/* 内容区域样式 */
.tab-content {
flex: 1;
position: relative;
overflow: hidden;
}
.tab-panel {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 12px;
overflow: auto;
background: #ffffff;
display: none;
}
.tab-panel.active {
display: block;
}
.tab-empty {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: #999;
font-size: 14px;
}
/* 滚动条样式 */
.tab-header::-webkit-scrollbar {
height: 6px;
}
.tab-header::-webkit-scrollbar-track {
background: #f0f0f0;
}
.tab-header::-webkit-scrollbar-thumb {
background: #c7d2ea;
border-radius: 3px;
}
.tab-panel::-webkit-scrollbar {
width: 12px;
height: 12px;
}
.tab-panel::-webkit-scrollbar-track {
background: #f5f7fb;
border-left: 1px solid #c7d2ea;
}
.tab-panel::-webkit-scrollbar-thumb {
background: linear-gradient(to bottom, #d0d6ea, #c0c7e0);
border: 1px solid #b0b6d6;
border-radius: 6px;
}
.tab-panel::-webkit-scrollbar-thumb:hover {
background: linear-gradient(to bottom, #c1c7e2, #b2b8d9);
}
</style>