forked from zhurui/management
107 lines
3.2 KiB
JavaScript
107 lines
3.2 KiB
JavaScript
import Vue from 'vue';
|
|
import loadingVue from './loading.vue';
|
|
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
|
|
import { PopupManager } from 'element-ui/src/utils/popup';
|
|
import afterLeave from 'element-ui/src/utils/after-leave';
|
|
import merge from 'element-ui/src/utils/merge';
|
|
|
|
const LoadingConstructor = Vue.extend(loadingVue);
|
|
|
|
const defaults = {
|
|
text: null,
|
|
fullscreen: true,
|
|
body: false,
|
|
lock: false,
|
|
customClass: ''
|
|
};
|
|
|
|
let fullscreenLoading;
|
|
|
|
LoadingConstructor.prototype.originalPosition = '';
|
|
LoadingConstructor.prototype.originalOverflow = '';
|
|
|
|
LoadingConstructor.prototype.close = function() {
|
|
if (this.fullscreen) {
|
|
fullscreenLoading = undefined;
|
|
}
|
|
afterLeave(this, _ => {
|
|
const target = this.fullscreen || this.body
|
|
? document.body
|
|
: this.target;
|
|
removeClass(target, 'el-loading-parent--relative');
|
|
removeClass(target, 'el-loading-parent--hidden');
|
|
if (this.$el && this.$el.parentNode) {
|
|
this.$el.parentNode.removeChild(this.$el);
|
|
}
|
|
this.$destroy();
|
|
}, 300);
|
|
this.visible = false;
|
|
};
|
|
|
|
const addStyle = (options, parent, instance) => {
|
|
let maskStyle = {};
|
|
if (options.fullscreen) {
|
|
instance.originalPosition = getStyle(document.body, 'position');
|
|
instance.originalOverflow = getStyle(document.body, 'overflow');
|
|
maskStyle.zIndex = PopupManager.nextZIndex();
|
|
} else if (options.body) {
|
|
instance.originalPosition = getStyle(document.body, 'position');
|
|
['top', 'left'].forEach(property => {
|
|
let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
|
|
maskStyle[property] = options.target.getBoundingClientRect()[property] +
|
|
document.body[scroll] +
|
|
document.documentElement[scroll] +
|
|
'px';
|
|
});
|
|
['height', 'width'].forEach(property => {
|
|
maskStyle[property] = options.target.getBoundingClientRect()[property] + 'px';
|
|
});
|
|
} else {
|
|
instance.originalPosition = getStyle(parent, 'position');
|
|
}
|
|
Object.keys(maskStyle).forEach(property => {
|
|
instance.$el.style[property] = maskStyle[property];
|
|
});
|
|
};
|
|
|
|
const Loading = (options = {}) => {
|
|
if (Vue.prototype.$isServer) return;
|
|
options = merge({}, defaults, options);
|
|
if (typeof options.target === 'string') {
|
|
options.target = document.querySelector(options.target);
|
|
}
|
|
options.target = options.target || document.body;
|
|
if (options.target !== document.body) {
|
|
options.fullscreen = false;
|
|
} else {
|
|
options.body = true;
|
|
}
|
|
if (options.fullscreen && fullscreenLoading) {
|
|
return fullscreenLoading;
|
|
}
|
|
|
|
let parent = options.body ? document.body : options.target;
|
|
let instance = new LoadingConstructor({
|
|
el: document.createElement('div'),
|
|
data: options
|
|
});
|
|
|
|
addStyle(options, parent, instance);
|
|
if (instance.originalPosition !== 'absolute' && instance.originalPosition !== 'fixed') {
|
|
addClass(parent, 'el-loading-parent--relative');
|
|
}
|
|
if (options.fullscreen && options.lock) {
|
|
addClass(parent, 'el-loading-parent--hidden');
|
|
}
|
|
parent.appendChild(instance.$el);
|
|
Vue.nextTick(() => {
|
|
instance.visible = true;
|
|
});
|
|
if (options.fullscreen) {
|
|
fullscreenLoading = instance;
|
|
}
|
|
return instance;
|
|
};
|
|
|
|
export default Loading;
|