Selaa lähdekoodia

Loading: fix loading not disappear in some condition (#9313)

FuryBean 7 vuotta sitten
vanhempi
commit
23a60a0ef6
4 muutettua tiedostoa jossa 43 lisäystä ja 16 poistoa
  1. 1 1
      examples/index.tpl
  2. 12 13
      packages/loading/src/directive.js
  3. 3 2
      packages/loading/src/index.js
  4. 27 0
      src/utils/after-leave.js

+ 1 - 1
examples/index.tpl

@@ -8,12 +8,12 @@
     <title>Element</title>
   </head>
   <body>
-    <div id="app"></div><% if (process.env.NODE_ENV === 'production') { %>
     <script>
       if (!window.Promise) {
         document.write('<script src="//cdn.jsdelivr.net/npm/es6-promise@4.1.1/dist/es6-promise.min.js"><\/script><script>ES6Promise.polyfill()<\/script>')
       }
     </script>
+    <div id="app"></div><% if (process.env.NODE_ENV === 'production') { %>
     <script src="//cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.runtime.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/vue-router@2.7.0/dist/vue-router.min.js"></script><% } %>
   </body>

+ 12 - 13
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) => {

+ 3 - 2
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;
 };
 

+ 27 - 0
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);
+};