UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

211 lines (174 loc) • 4.08 kB
import { createVNode, render } from 'vue'; import LoadingBar from './index.vue'; type options = { percent?: number; status?: string; color?: string; failedColor?: string; height?: number; visible?: boolean; duration?: number; }; // 实例列表 let instances; // 进度条的颜色 let color = 'primary'; // 失败时的进度条颜色 let failedColor = 'error'; // 进度条高度 let height = 2; // 隐藏时的持续时间 let duration = 800; let timer: ReturnType<typeof setInterval> | null; const newInstance = (options: options) => { // 实例对象 const vm = instances || createVNode(LoadingBar, options); const container = document.createElement('div'); // 清除通知元素防止内存泄漏 vm.props.onDestroy = () => { // 既然元素被销毁了,那么VNode也应该被GC回收 // 我们不想造成任何内存泄漏,因为我们已经返回 vm 作为对用户的引用 // 以便我们手动将其设置为 false。 render(null, container); }; render(vm, container); // 当 close 函数被调用时,实例将删除此项。 所以我们不需要担心。 instances = vm; document.body.appendChild(container.firstElementChild); return { update(options: options) { const data = vm.component.proxy.data; if (options.percent !== undefined) { data.percent = options.percent; } data.visible = options.visible; if (options.status) { data.status = options.status; } }, component: vm, // 销毁 destroy() { document.body.removeChild( document.getElementsByClassName('ivue-loading-bar')[0] ); }, }; }; // 获取组件实例 const getIvueLoadingBarInstance = () => { instances = instances || newInstance({ color: color, failedColor: failedColor, height: height, }); return instances; }; // 更新组件 const update = (options: options) => { const instance = getIvueLoadingBarInstance(); instance.update(options); }; // 清除定时器 const clearTimer = () => { if (timer) { clearInterval(timer); timer = null; } }; // 隐藏组件 const hide = () => { setTimeout(() => { update({ visible: false, }); setTimeout(() => { update({ percent: 0, }); }, 500); }, duration); }; export default { // 开始 start() { // 如果已经开始了不执行 if (timer) { return; } let percent = 0; update({ percent: percent, status: 'success', visible: true, }); // 设置进度 timer = setInterval(() => { percent += Math.floor(Math.random() * 3 + 1); // 进度大于95清除定时器 if (percent > 95) { clearTimer(); } update({ percent: percent, status: 'success', visible: true, }); }, 200); }, // 更新 update(percent: number) { clearTimer(); update({ percent: percent, status: 'success', visible: true, }); }, // 完成 finish() { clearTimer(); update({ percent: 100, status: 'success', visible: true, }); // 隐藏组件 hide(); }, // 错误 error() { clearTimer(); update({ percent: 100, status: 'error', visible: true, }); // 隐藏组件 hide(); }, // 公共参数 config(options: options) { if (options.color) { color = options.color; } if (options.failedColor) { failedColor = options.failedColor; } if (options.height) { height = options.height; } if (options.duration) { duration = options.duration; } }, // 销毁 destroy() { clearTimer(); const _instance = getIvueLoadingBarInstance(); instances = null; _instance.destroy(); }, };