UNPKG

@prettyy/ui

Version:

vue2 UI

137 lines (118 loc) 4.62 kB
import loadingVue from "../loading/src/main.vue" import afterLeave from "../../utils/after-leave" import { getStyle, removeClass, addClass } from "../../utils/dom" import { t } from '../../locale' import vue from 'vue' const VLoading = vue.extend(loadingVue) const loadingDirective = {} loadingDirective.install = Vue => { const insertDom = (parent, el, binding) => { if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') { Object.keys(el.maskStyle).forEach(property => { el.mask.style[property] = el.maskStyle[property] }) if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed' && el.originalPosition !== 'sticky') { addClass(parent, 'vl-loading-parent--relative') } if (binding.modifiers.lock) { addClass(parent, 'vl-loading-parent--hidden') } el.domVisible = true parent.appendChild(el.mask) Vue.nextTick(() => { if (el.instance.hiding) { el.instance.$emit('after-leave') } else { el.instance.visible = true } }) el.domInserted = true } else if (el.domVisible && el.instance.hiding === true) { el.instance.visible = true el.instance.hiding = false } } const toggleLoading = (el, binding) => { if (binding.value) { vue.nextTick(() => { if (binding.modifiers.fullscreen) { el.originalPosition = getStyle(document.body, 'position') el.originalOverflow = getStyle(document.body, 'overflow') addClass(el.mask, 'is-fullscreen') insertDom(document.body, el, binding) } else { removeClass(el.mask, 'is-fullscreen') // 设置了基于body if (binding.modifiers.body) { el.originalPosition = getStyle(document.body, 'position'); ['top', 'left'].forEach(property => { const scroll = property === 'top' ? 'scrollTop' : 'scrollLeft' el.maskStyle[property] = el.getBoundingClientRect()[property] + document.body[scroll] + document.documentElement[scroll] - parseInt(getStyle(document.body, `margin-${property}`), 10) + 'px' }); ['height', 'width'].forEach(property => { el.maskStyle[property] = document.body.getBoundingClientRect()[property] + 'px' }) insertDom(document.body, el, binding) } else { el.originalPosition = getStyle(el, 'position') insertDom(el, el, binding) } } }) } else { // eslint-disable-next-line no-unused-vars afterLeave(el.instance, _ => { if (!el.instance.hiding) return el.domVisible = false const target = binding.modifiers.body ? document.body : el removeClass(target, 'vl-loading-parent--relative') removeClass(target, 'vl-loading-parent--hidden') el.instance.hiding = false }, 300, true) el.instance.visible = false el.instance.hiding = true } } Vue.directive('loading', { bind: function (el, binding, vnode) { const textExr = el.getAttribute('loading-text') || t('vl.loading.text') const backgroundExr = el.getAttribute('loading-background') || '' const customClassExr = el.getAttribute('loading-custom-class') const vm = vnode.context const mask = new VLoading({ el: document.createElement('div'), data: { text: vm && vm[textExr] || textExr, background: vm && vm[backgroundExr] || backgroundExr, customClass: vm && vm[customClassExr] || customClassExr, fullscreen: !!binding.modifiers.fullscreen } }) el.instance = mask el.mask = mask.$el el.maskStyle = {} binding.value && toggleLoading(el, binding) }, inserted: function (){}, update: function (el, binding) { el.instance.setText(el.getAttribute('loading-text')) if (binding.oldValue !== binding.value) { toggleLoading(el, binding) } }, unbind: function (el, binding) { if (el.domInserted) { el.mask && el.mask.parentNode && el.mask.parentNode.removeChild(el.mask) toggleLoading(el, { value: false, modifiers: binding.modifiers }) } el.instance && el.instance.$destroy() } }) } export default loadingDirective