u
This commit is contained in:
1 parent
07e0001b87
commit
46cbb2f50d
543 files changed
+32576
-4231
No files matched your search
@@ -0,0 +1,38 @@
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
export type ProgressStatus = 'uploading' | 'completed' | 'failed'
|
||||
@@ -0,0 +1,128 @@
|
||||
<script setup lang="ts">
|
||||
import type { ProgressStatus } from '.'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
// 状态变量
|
||||
const visible = ref(false)
|
||||
const percent = ref(0)
|
||||
const statusText = ref('正在上传,请稍候')
|
||||
const status = ref<ProgressStatus>('uploading')
|
||||
|
||||
// 监听 percent 变化,更新状态文本
|
||||
watch(percent, (newPercent) => {
|
||||
const clampedPercent = Math.min(newPercent, 1)
|
||||
percent.value = clampedPercent
|
||||
|
||||
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 ? '' : '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 = Number.parseFloat((p / 100).toFixed(2)) // 保留两位小数
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close,
|
||||
setPercent,
|
||||
setStatus: (newStatus: ProgressStatus) => {
|
||||
status.value = newStatus // 使用 ProgressStatus 类型
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<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" :class="[status === 'failed' ? 'error' : '']">
|
||||
{{ statusText }}
|
||||
</div>
|
||||
<el-progress :percentage="percent" :stroke-width="10" :status="getProgressStatus" />
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<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