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

1 month ago
<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>