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;
标签:const,进度条,color,vm,height,width,background,vue3,上传 From: https://www.cnblogs.com/xzc666/p/17638217.html