Skip to content

Commit b882342

Browse files
author
Taois
committed
feat: 顶部关闭按钮优化
居中弹窗
1 parent b59e64c commit b882342

File tree

1 file changed

+205
-15
lines changed

1 file changed

+205
-15
lines changed

dashboard/src/components/Header.vue

Lines changed: 205 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,50 @@
4040
<icon-expand/>
4141
</template>
4242
</a-button>
43-
<a-popconfirm content="你确认要关闭当前应用?" @ok="closeWindow">
44-
<a-button shape="circle">
45-
<template #icon>
46-
<icon-close/>
47-
</template>
48-
</a-button>
49-
</a-popconfirm>
50-
43+
<a-button shape="circle" @click="showCloseConfirm">
44+
<template #icon>
45+
<icon-close/>
46+
</template>
47+
</a-button>
48+
</div>
5149

50+
<!-- 全屏居中确认弹窗 -->
51+
<div v-if="showConfirmModal" class="confirm-modal-overlay" @click="hideCloseConfirm">
52+
<div class="confirm-modal" @click.stop>
53+
<div class="modal-header">
54+
<icon-exclamation-circle-fill class="warning-icon" />
55+
<h3 class="modal-title">确认关闭</h3>
56+
</div>
57+
<div class="modal-content">
58+
<p class="modal-message">你确认要关闭当前应用吗?</p>
59+
<p class="modal-submessage">关闭后将退出应用程序</p>
60+
</div>
61+
<div class="modal-footer">
62+
<a-button class="cancel-btn" @click="hideCloseConfirm">
63+
取消
64+
</a-button>
65+
<a-button type="primary" status="danger" class="confirm-btn" @click="confirmClose">
66+
确认关闭
67+
</a-button>
68+
</div>
69+
</div>
5270
</div>
5371
</a-layout-header>
5472
</template>
5573

5674
<script>
57-
import {defineComponent} from 'vue';
75+
import {defineComponent, ref} from 'vue';
5876
import {Message} from '@arco-design/web-vue';
5977
6078
export default defineComponent({
6179
components: {},
80+
setup() {
81+
const showConfirmModal = ref(false);
82+
83+
return {
84+
showConfirmModal
85+
};
86+
},
6287
methods: {
6388
goBack() {
6489
Message.info("前进按钮");
@@ -87,12 +112,41 @@ export default defineComponent({
87112
// 最大化窗口的逻辑
88113
this.enterFullScreen()
89114
},
90-
closeWindow() {
91-
Message.info("将在1秒后关闭窗口");
92-
// 关闭窗口的逻辑,可以通过调用系统接口来实现
93-
setTimeout(function () {
94-
window.open("about:blank", "_self").close()
95-
}, 1000)
115+
showCloseConfirm() {
116+
this.showConfirmModal = true;
117+
},
118+
hideCloseConfirm() {
119+
this.showConfirmModal = false;
120+
},
121+
confirmClose() {
122+
this.showConfirmModal = false;
123+
Message.info("正在关闭应用...");
124+
125+
// 尝试多种关闭方式
126+
try {
127+
// 方式1: 尝试关闭当前窗口
128+
if (window.opener) {
129+
window.close();
130+
} else {
131+
// 方式2: 如果是主窗口,尝试使用about:blank方式
132+
window.open('about:blank', '_self');
133+
window.close();
134+
}
135+
136+
// 方式3: 如果上述方式都失败,提供备用方案
137+
setTimeout(() => {
138+
// 检查窗口是否已关闭
139+
if (!window.closed) {
140+
Message.warning("无法自动关闭窗口,请手动关闭浏览器标签页");
141+
// 可以考虑跳转到一个关闭页面
142+
window.location.href = 'about:blank';
143+
}
144+
}, 500);
145+
146+
} catch (error) {
147+
console.error('关闭窗口失败:', error);
148+
Message.error("关闭失败,请手动关闭浏览器标签页");
149+
}
96150
},
97151
enterFullScreen() {
98152
let element = document.documentElement;
@@ -252,6 +306,114 @@ export default defineComponent({
252306
background: var(--color-primary-7);
253307
}
254308
309+
/* 全屏居中确认弹窗样式 */
310+
.confirm-modal-overlay {
311+
position: fixed;
312+
top: 0;
313+
left: 0;
314+
right: 0;
315+
bottom: 0;
316+
background: rgba(0, 0, 0, 0.6);
317+
backdrop-filter: blur(4px);
318+
display: flex;
319+
align-items: center;
320+
justify-content: center;
321+
z-index: 10000;
322+
animation: fadeIn 0.3s ease-out;
323+
}
324+
325+
.confirm-modal {
326+
background: var(--color-bg-1);
327+
border-radius: 12px;
328+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
329+
min-width: 400px;
330+
max-width: 500px;
331+
padding: 0;
332+
animation: slideIn 0.3s ease-out;
333+
border: 1px solid var(--color-border-2);
334+
}
335+
336+
.modal-header {
337+
display: flex;
338+
align-items: center;
339+
padding: 24px 24px 16px;
340+
border-bottom: 1px solid var(--color-border-2);
341+
}
342+
343+
.warning-icon {
344+
font-size: 24px;
345+
color: #ff6b35;
346+
margin-right: 12px;
347+
}
348+
349+
.modal-title {
350+
margin: 0;
351+
font-size: 18px;
352+
font-weight: 600;
353+
color: var(--color-text-1);
354+
}
355+
356+
.modal-content {
357+
padding: 20px 24px;
358+
}
359+
360+
.modal-message {
361+
margin: 0 0 8px 0;
362+
font-size: 16px;
363+
color: var(--color-text-1);
364+
line-height: 1.5;
365+
}
366+
367+
.modal-submessage {
368+
margin: 0;
369+
font-size: 14px;
370+
color: var(--color-text-3);
371+
line-height: 1.4;
372+
}
373+
374+
.modal-footer {
375+
display: flex;
376+
justify-content: flex-end;
377+
gap: 12px;
378+
padding: 16px 24px 24px;
379+
border-top: 1px solid var(--color-border-2);
380+
}
381+
382+
.cancel-btn {
383+
min-width: 80px;
384+
height: 36px;
385+
border-radius: 6px;
386+
font-weight: 500;
387+
}
388+
389+
.confirm-btn {
390+
min-width: 100px;
391+
height: 36px;
392+
border-radius: 6px;
393+
font-weight: 500;
394+
}
395+
396+
/* 动画效果 */
397+
@keyframes fadeIn {
398+
from {
399+
opacity: 0;
400+
}
401+
to {
402+
opacity: 1;
403+
}
404+
}
405+
406+
@keyframes slideIn {
407+
from {
408+
opacity: 0;
409+
transform: translateY(-20px) scale(0.95);
410+
}
411+
to {
412+
opacity: 1;
413+
transform: translateY(0) scale(1);
414+
}
415+
}
416+
255417
/* 响应式设计 */
256418
@media (max-width: 768px) {
257419
.header-left,
@@ -266,6 +428,12 @@ export default defineComponent({
266428
.header-center :deep(.arco-input-search) {
267429
max-width: 250px;
268430
}
431+
432+
.confirm-modal {
433+
min-width: 320px;
434+
max-width: 90vw;
435+
margin: 20px;
436+
}
269437
}
270438
271439
@media (max-width: 480px) {
@@ -296,5 +464,27 @@ export default defineComponent({
296464
width: 28px;
297465
height: 28px;
298466
}
467+
468+
.confirm-modal {
469+
min-width: 280px;
470+
margin: 16px;
471+
}
472+
473+
.modal-header,
474+
.modal-content,
475+
.modal-footer {
476+
padding-left: 20px;
477+
padding-right: 20px;
478+
}
479+
480+
.modal-footer {
481+
flex-direction: column;
482+
gap: 8px;
483+
}
484+
485+
.cancel-btn,
486+
.confirm-btn {
487+
width: 100%;
488+
}
299489
}
300490
</style>

0 commit comments

Comments
 (0)