u
This commit is contained in:
1 parent
68e0785ec6
commit
57c0d98f11
189 files changed
+34329
No files matched your search
@@ -0,0 +1,39 @@
|
||||
import { createApp } from "vue";
|
||||
import UploadProgress from "./index.vue";
|
||||
|
||||
let app: ReturnType<typeof createApp> | null = null;
|
||||
let instance: any = null;
|
||||
|
||||
export function showUploadProgress(status: ProgressStatus = "uploading") {
|
||||
if (!app) {
|
||||
const container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
|
||||
app = createApp(UploadProgress);
|
||||
instance = app.mount(container);
|
||||
}
|
||||
instance.open();
|
||||
instance.setStatus(status); // 外部传入状态
|
||||
}
|
||||
|
||||
export function updateUploadProgress(percent: number, status: ProgressStatus = "uploading") {
|
||||
if (instance) {
|
||||
instance.setPercent(percent);
|
||||
instance.setStatus(status); // 外部传入状态
|
||||
|
||||
if (percent >= 100) {
|
||||
setTimeout(() => {
|
||||
closeUploadProgress();
|
||||
}, 800); // 100%后等一下再关闭,显得自然
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function closeUploadProgress() {
|
||||
if (instance) {
|
||||
instance.close();
|
||||
}
|
||||
}
|
||||
|
||||
// 如果你有 ProgressStatus 类型的需求,确保你导出它
|
||||
export type ProgressStatus = "uploading" | "completed" | "failed";
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<transition name="fade">
|
||||
<div v-if="visible" class="upload-progress-mask">
|
||||
<div class="upload-progress-card">
|
||||
<div :class="['upload-progress-title', status === 'failed' ? 'error' : '']">{{ statusText }}</div>
|
||||
<a-progress :percent="percent" :stroke-width="10" :status="getProgressStatus" />
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { Progress as AProgress } from "@arco-design/web-vue";
|
||||
import { ProgressStatus } from ".";
|
||||
|
||||
// 状态变量
|
||||
const visible = ref(false);
|
||||
const percent = ref(0);
|
||||
const statusText = ref("正在上传,请稍候");
|
||||
const status = ref<ProgressStatus>("uploading"); // 使用 ProgressStatus 类型
|
||||
|
||||
// 监听 percent 变化,更新状态文本
|
||||
watch(percent, (newPercent) => {
|
||||
const clampedPercent = Math.min(newPercent, 1); // 确保 percent 不超过 1
|
||||
percent.value = clampedPercent; // 更新实际的 percent 值
|
||||
|
||||
if (clampedPercent === 1) {
|
||||
status.value = "completed";
|
||||
} else if (clampedPercent < 1 && status.value !== "failed") {
|
||||
status.value = "uploading";
|
||||
}
|
||||
});
|
||||
|
||||
// 监听上传状态变化,更新状态文本
|
||||
watch(status, (newStatus) => {
|
||||
if (newStatus === "completed") {
|
||||
statusText.value = "上传完毕";
|
||||
} else if (newStatus === "uploading") {
|
||||
statusText.value = "正在上传,请稍候 . . .";
|
||||
} else if (newStatus === "failed") {
|
||||
statusText.value = "上传失败,请稍后再试 . . .";
|
||||
}
|
||||
});
|
||||
|
||||
// 获取进度条状态,上传失败时显示为 "exception"
|
||||
const getProgressStatus = computed(() => {
|
||||
if (status.value === "failed") {
|
||||
return "exception";
|
||||
}
|
||||
return percent.value < 1 ? "normal" : "success";
|
||||
});
|
||||
|
||||
// 控制上传进度的函数
|
||||
function open() {
|
||||
percent.value = 0;
|
||||
visible.value = true;
|
||||
status.value = "uploading"; // 开始上传时重置状态
|
||||
statusText.value = "正在上传,请稍候 . . .";
|
||||
}
|
||||
|
||||
function close() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
function setPercent(p: number) {
|
||||
percent.value = parseFloat((p / 100).toFixed(2)); // 保留两位小数
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close,
|
||||
setPercent,
|
||||
setStatus: (newStatus: ProgressStatus) => {
|
||||
status.value = newStatus; // 使用 ProgressStatus 类型
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.upload-progress-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 3000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.upload-progress-card {
|
||||
background: #ffffff;
|
||||
padding: 40px 50px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
|
||||
text-align: center;
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
.upload-progress-title {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.upload-progress-title.error {
|
||||
color: red; /* 上传失败时,字体颜色变为红色 */
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user