You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
3.3 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div v-if="isVisible" class="progress-container" :class="{ minimized: isMinimized }">
<!-- 进度条头部 -->
<div class="progress-header">
<div class="progress-info" v-if="!isMinimized">
{{ message }}
</div>
<div class="progress-controls">
<!-- 最小化/还原按钮 -->
<button
@click="toggleMinimize"
class="control-btn minimize-btn"
>
{{ isMinimized ? '还原 □' : '' }}
</button>
<!-- 停止按钮(触发父组件隐藏) -->
<!-- <button
@click="handleStop"
class="control-btn stop-btn"
>
×
</button> -->
</div>
</div>
<!-- 正常尺寸进度条 -->
<div v-if="isMinimized" class="minimized-progress">
<div class="mini-progress-bar">
<div
class="mini-progress-fill"
:style="{ width: `${progress}%` }"
> {{ progress }}%</div>
</div>
</div>
<!-- 非最小化进度条 -->
<div v-else class="progress-bar">
<div
class="progress-fill"
:style="{ width: `${progress}%` }"
>{{ progress }}%</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 接收父组件传递的属性
const props = defineProps({
progress: { type: Number, required: true }, // 当前进度0-100
message: { type: String, default: '处理中...' }, // 提示信息
isVisible: { type: Boolean, default: true } // 是否显示
});
// 定义向父组件发送的事件
const emit = defineEmits(['hide']);
// 子组件内部状态(最小化状态)
const isMinimized = ref(false);
// 切换最小化状态
const toggleMinimize = () => {
isMinimized.value = !isMinimized.value;
};
// 处理停止按钮点击(通知父组件隐藏)
const handleStop = () => {
emit('hide');
};
</script>
<style scoped>
.progress-container {
position: fixed;
top: 50%;
left: 50%;
transform: translateX(-50%);
width: 50%;
background: #ffffff;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
padding: 16px;
z-index: 1000;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 最小化状态样式 */
.minimized {
top: auto;
bottom: 20px;
right: 20px;
left: auto;
transform: none;
width: 240px;
padding: 12px;
}
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
font-size: 14px;
}
.progress-info {
font-weight: 500;
color: #333;
display: flex;
flex-direction: column;
}
.progress-controls {
display: flex;
gap: 8px;
}
.control-btn {
border: none;
background: none;
cursor: pointer;
padding: 4px 8px;
border-radius: 4px;
transition: all 0.2s;
}
.minimize-btn:hover {
background: #f0f0f0;
color: #2c3e50;
}
.stop-btn:hover {
background: #ffebee;
color: #e53935;
}
/* 进度条样式 */
.progress-bar, .minimized-progress {
height: 20px;
background: #f5f5f5;
border-radius: 10px;
overflow: hidden;
}
.mini-progress-bar {
height: 6px;
background: #f5f5f5;
border-radius: 3px;
}
.progress-fill, .mini-progress-fill {
height: 100%;
width:100px;
background: linear-gradient(90deg, #42b883, #3498db);
border-radius: inherit;
transition: width 0.3s ease;
justify-content: center;
text-align: center;
}
</style>