166 lines
4.3 KiB
Vue
166 lines
4.3 KiB
Vue
<template>
|
|
<div class="desktop-container">
|
|
<div class="app-window" :class="{ 'is-maximized': isMaximized }">
|
|
|
|
<header class="window-header" @dblclick="toggleMaximize">
|
|
<div class="header-left">
|
|
<div class="app-icon">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
|
</svg>
|
|
</div>
|
|
<span class="app-title">IM Connect</span>
|
|
</div>
|
|
|
|
<div class="window-controls">
|
|
<button class="control-btn minimize" @click="minimize" title="最小化">
|
|
<svg width="10" height="10" viewBox="0 0 10 1">
|
|
<rect width="10" height="1" fill="currentColor" />
|
|
</svg>
|
|
</button>
|
|
<button class="control-btn maximize" @click="toggleMaximize" title="最大化/还原">
|
|
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.2">
|
|
<rect x="1.5" y="1.5" width="7" height="7" v-if="!isMaximized"/>
|
|
<path d="M3 1h6v6H3z M1 3h6v6H1z" v-else fill="currentColor" fill-opacity="0.5"/>
|
|
</svg>
|
|
</button>
|
|
<button class="control-btn close" @click="close" title="关闭">
|
|
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round">
|
|
<path d="M1 1L9 9M9 1L1 9" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="window-body">
|
|
<slot></slot>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
|
|
const isMaximized = ref(false)
|
|
|
|
function minimize() {
|
|
console.log('Window: Minimize')
|
|
}
|
|
function toggleMaximize() {
|
|
isMaximized.value = !isMaximized.value
|
|
console.log('Window: Maximize/Restore')
|
|
}
|
|
function close() {
|
|
console.log('Window: Close')
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 模拟桌面背景 */
|
|
.desktop-container {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
/* 一个高级的模糊背景,衬托窗口 */
|
|
background: radial-gradient(circle at 50% 30%, #eef2ff, #e2e8f0);
|
|
padding: 20px;
|
|
box-sizing: border-box;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
}
|
|
|
|
/* 窗口主体 */
|
|
.app-window {
|
|
width: 960px;
|
|
height: 600px;
|
|
/* 响应式限制 */
|
|
max-width: 95vw;
|
|
max-height: 90vh;
|
|
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #ffffff;
|
|
border-radius: 10px; /* 现代圆角 */
|
|
/* 精致的窗口阴影:一层边框 + 两层阴影模拟浮起 */
|
|
box-shadow:
|
|
0 0 0 1px rgba(0, 0, 0, 0.06),
|
|
0 8px 20px rgba(0, 0, 0, 0.08),
|
|
0 20px 50px rgba(0, 0, 0, 0.12);
|
|
overflow: hidden;
|
|
transition: width 0.3s, height 0.3s, border-radius 0.3s;
|
|
}
|
|
|
|
/* 最大化状态 */
|
|
.app-window.is-maximized {
|
|
width: 100vw;
|
|
height: 100vh;
|
|
max-width: none;
|
|
max-height: none;
|
|
border-radius: 0;
|
|
}
|
|
|
|
/* 头部 Header */
|
|
.window-header {
|
|
height: 38px; /* 经典桌面应用高度 */
|
|
background: #f8fafc; /* 极浅的灰,区分内容区 */
|
|
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 0 0 12px;
|
|
user-select: none;
|
|
-webkit-app-region: drag; /* Electron/Tauri 拖拽支持 */
|
|
}
|
|
|
|
.header-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
color: #475569;
|
|
}
|
|
.app-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
color: #6366f1; /* 品牌色 */
|
|
}
|
|
.app-title {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* 窗口控制按钮 */
|
|
.window-controls {
|
|
display: flex;
|
|
height: 100%;
|
|
-webkit-app-region: no-drag;
|
|
}
|
|
.control-btn {
|
|
width: 46px; /* 较宽的点击区域,类似 Win10/11 */
|
|
height: 100%;
|
|
border: none;
|
|
background: transparent;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #64748b;
|
|
cursor: default;
|
|
transition: all 0.2s;
|
|
}
|
|
.control-btn:hover {
|
|
background: rgba(0, 0, 0, 0.05);
|
|
color: #1e293b;
|
|
}
|
|
.control-btn.close:hover {
|
|
background: #ef4444;
|
|
color: white;
|
|
}
|
|
|
|
/* 内容区 */
|
|
.window-body {
|
|
flex: 1;
|
|
position: relative;
|
|
overflow: hidden; /* 确保内容不溢出圆角 */
|
|
background: #fff;
|
|
}
|
|
</style> |