From 23a60a0ef6f5ef86922529cec32896e4bc93fa7e Mon Sep 17 00:00:00 2001 From: FuryBean Date: Thu, 18 Jan 2018 11:44:19 +0800 Subject: [PATCH] Loading: fix loading not disappear in some condition (#9313) --- examples/index.tpl | 2 +- packages/loading/src/directive.js | 25 ++++++++++++------------- packages/loading/src/index.js | 5 +++-- src/utils/after-leave.js | 27 +++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 src/utils/after-leave.js diff --git a/examples/index.tpl b/examples/index.tpl index fcc29fb83..f6d791ba7 100644 --- a/examples/index.tpl +++ b/examples/index.tpl @@ -8,12 +8,12 @@ Element -
<% if (process.env.NODE_ENV === 'production') { %> +
<% if (process.env.NODE_ENV === 'production') { %> <% } %> diff --git a/packages/loading/src/directive.js b/packages/loading/src/directive.js index c2904a0ab..87579bc6d 100644 --- a/packages/loading/src/directive.js +++ b/packages/loading/src/directive.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import Loading from './loading.vue'; import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom'; +import afterLeave from 'element-ui/src/utils/after-leave'; const Mask = Vue.extend(Loading); exports.install = Vue => { @@ -36,19 +37,17 @@ exports.install = Vue => { } }); } else { - if (el.domVisible) { - el.instance.$once('after-leave', _ => { - el.domVisible = false; - const target = binding.modifiers.fullscreen || binding.modifiers.body - ? document.body - : el; - removeClass(target, 'el-loading-parent--relative'); - removeClass(target, 'el-loading-parent--hidden'); - el.instance.hiding = false; - }); - el.instance.visible = false; - el.instance.hiding = true; - } + afterLeave(el.instance, _ => { + el.domVisible = false; + const target = binding.modifiers.fullscreen || binding.modifiers.body + ? document.body + : el; + removeClass(target, 'el-loading-parent--relative'); + removeClass(target, 'el-loading-parent--hidden'); + el.instance.hiding = false; + }, 300, true); + el.instance.visible = false; + el.instance.hiding = true; } }; const insertDom = (parent, el, binding) => { diff --git a/packages/loading/src/index.js b/packages/loading/src/index.js index c8aa0a78b..3a19480a4 100644 --- a/packages/loading/src/index.js +++ b/packages/loading/src/index.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import loadingVue from './loading.vue'; import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom'; +import afterLeave from 'element-ui/src/utils/after-leave'; import merge from 'element-ui/src/utils/merge'; const LoadingConstructor = Vue.extend(loadingVue); @@ -22,7 +23,7 @@ LoadingConstructor.prototype.close = function() { if (this.fullscreen) { fullscreenLoading = undefined; } - this.$on('after-leave', _ => { + afterLeave(this, _ => { const target = this.fullscreen || this.body ? document.body : this.target; @@ -32,7 +33,7 @@ LoadingConstructor.prototype.close = function() { this.$el.parentNode.removeChild(this.$el); } this.$destroy(); - }); + }, 300); this.visible = false; }; diff --git a/src/utils/after-leave.js b/src/utils/after-leave.js new file mode 100644 index 000000000..dd6cf2a62 --- /dev/null +++ b/src/utils/after-leave.js @@ -0,0 +1,27 @@ +/** + * Bind after-leave event for vue instance. Make sure after-leave is called in any browsers. + * + * @param {Vue} instance Vue instance. + * @param {Function} callback callback of after-leave event + * @param {Number} speed the speed of transition, default value is 300ms + * @param {Boolean} once weather bind after-leave once. default value is false. + */ +export default function(instance, callback, speed = 300, once = false) { + if (!instance || !callback) throw new Error('instance & callback is required'); + let called = false; + const afterLeaveCallback = function() { + if (called) return; + called = true; + if (callback) { + callback.apply(null, arguments); + } + }; + if (once) { + instance.$once('after-leave', afterLeaveCallback); + } else { + instance.$on('after-leave', afterLeaveCallback); + } + setTimeout(() => { + afterLeaveCallback(); + }, speed + 100); +};