vue3 文件上传进度条组件
需要在main.js中use一下
import UploadProgress from '@/components/UploadProgress/index.js'
const app = createApp(App).use(UploadProgress)
使用
// 上传文件方法,$uploadProgress.show()为展示,close关闭,$uploadProgress在index.js中已经注册
const upLoadProgressNum = ref(0)
const upload = (params, type) => { proxy.$uploadProgress.show({ title: '上传文件', hint: '文件正在上传请勿刷新或关闭页面', percentage: upLoadProgressNum }) upload(params, (progressEvent) => { if (progressEvent.lengthComputable) { upLoadProgressNum.value = progressEvent.loaded / progressEvent.total * 100 //实时获取上传进度 } }).then((res) => { const code = res.code const data = res.data; if (code === 200) { ElMessage.success('上传成功'); proxy.$uploadProgress.close() } else { ElMessage.error(res.msg); } }) }
index.vue文件
<template>
<div class="confirm-modal">
<transition name="fade">
<div class="modal-dialog" @click="clickMaskToClose ? handleCancel() : null" v-if="visible" @touchmove.prevent>
<div class="modal">
<div class="modal-title" v-if="title">
{{ title }}
</div>
<div class="modal-content">
<div class="lineBox">
<div class="line" :style="{'width': parseInt(percentage)+'%'}">
</div>
</div>
<div class="num">
{{parseInt(percentage)}}%
</div>
</div>
<div class="hint" v-if="hint">
{{parseInt(percentage) === 100 ? '数据整在处理请耐心等待...' : hint}}
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
import {ref, defineComponent, reactive, toRefs} from "vue";
export default defineComponent({
props: {
visible: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "提示",
},
percentage: {
type: Number,
default: 0,
},
hint: {
type: String,
default: '',
},
clickMaskToClose: {
type: Boolean,
default: false,
}, // 点击遮罩是否隐藏
},
emits: {
onConfirm: null,
onCancel: null,
},
setup(props, context) {
let percentage = ref(0)
let tempData = Object.assign({}, props);
const propsData = reactive(tempData);
const handleConfirm = () => {
propsData.visible = false;
context.emit("onConfirm");
};
const handleCancel = () => {
propsData.visible = false;
context.emit("onCancel");
};
return {
...toRefs(propsData),
handleCancel,
handleConfirm
};
},
});
</script>
<style lang='scss' scoped>
.modal-dialog {
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9999;
transform: translateZ(9999px);
letter-spacing: 0;
background: rgba(0, 0, 0, 0.3);
}
.modal {
position: absolute;
top: 40%;
left: 50%;
z-index: 9000;
width: 350px;
transform: translate(-50%, -50%);
box-sizing: border-box;
background: #fff;
border-radius: 4px;
padding: 15px;
}
.modal-title {
font-size: 16px;
line-height: 25px;
color: #030303;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.hint {
font-size: 13px;
color: #e6a23c;
}
.modal-content {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
line-height: 21px;
color: #5e5f64;
padding: 10px 0;
.lineBox {
position: relative;
width: 100%;
height: 15px;
background-color: #ebeef5;
border-radius: 2px;
.line {
position: absolute;
top: 0;
left: 0;
height: 15px;
border-radius: 2px;
background-color: #409eff;
transition: width 0.5s;
}
}
.num {
text-align: right;
width: 50px;
}
}
.no-title-content {
font-size: 16px;
padding: 28px;
color: #333333;
}
.modal-right {
padding-right: 10px;
width: 36px;
background: #f2f2f2;
color: rgba(0, 16, 38, 0.3);
font-size: 12px;
border-radius: 0 4px 4px 0;
position: absolute;
top: 0;
right: 0;
bottom: 0;
}
.split-line-top {
height: 1px;
transform: scale(1, 0.5);
background: #e8eaef;
}
.modal-footer {
width: 100%;
display: flex;
align-items: center;
height: 52px;
font-size: 16px;
line-height: 52px;
text-align: center;
}
.split-line-center {
width: 1px;
height: 100%;
transform: scale(0.5, 1);
background: #e8eaef;
}
.btn-cancel {
flex: 1;
color: #696d76;
}
.btn-confirm {
position: relative;
flex: 1;
color: #409eff;
}
</style>
index.js文件
import { createApp } from "vue";
import uploadProgressIndex from "./index.vue";
const UploadProgressPlugin = {};
let $vm;
const defaultsOptions = {
title: "提示",
content: "内容",
hint: "",
clickMaskToClose: false,
};
const initInstance = () => {
const app = createApp(uploadProgressIndex);
const container = document.createElement("div");
$vm = app.mount(container);
document.body.appendChild(container);
};
UploadProgressPlugin.install = (app) => {
const uploadProgress = {
show(options) {
if (!$vm) initInstance();
options = Object.assign({}, defaultsOptions, options);
for (const i in options) {
$vm[i] = options[i];
}
$vm.visible = true;
return $vm;
},
close() {
$vm.percentage = 0
if ($vm) $vm.visible = false;
},
};
app.config.globalProperties.$uploadProgress = uploadProgress;
};
export default UploadProgressPlugin;