Browse Source

Tabs: fix order of TabNav when array is sorted (#12846)

* Tabs: fix order of TabNav when array is sorted

* update tabs.vue

* update test cases
hetech 6 years ago
parent
commit
17d817c0ce
3 changed files with 29 additions and 32 deletions
  1. 0 11
      packages/tabs/src/tab-pane.vue
  2. 21 13
      packages/tabs/src/tabs.vue
  3. 8 8
      test/unit/specs/tabs.spec.js

+ 0 - 11
packages/tabs/src/tab-pane.vue

@@ -49,17 +49,6 @@
       }
     },
 
-    mounted() {
-      this.$parent.addPanes(this);
-    },
-
-    destroyed() {
-      if (this.$el && this.$el.parentNode) {
-        this.$el.parentNode.removeChild(this.$el);
-      }
-      this.$parent.removePanes(this);
-    },
-
     watch: {
       label() {
         this.$parent.$forceUpdate();

+ 21 - 13
packages/tabs/src/tabs.vue

@@ -53,6 +53,17 @@
     },
 
     methods: {
+      calcPaneInstances() {
+        if (this.$slots.default) {
+          const paneSlots = this.$slots.default.filter(vnode => vnode.tag &&
+            vnode.componentOptions && vnode.componentOptions.Ctor.options.name === 'ElTabPane');
+          // update indeed
+          const panes = paneSlots.map(({ componentInstance }) => componentInstance);
+          if (!(panes.length === this.panes.length && panes.every((pane, index) => pane === this.panes[index]))) {
+            this.panes = panes;
+          }
+        }
+      },
       handleTabClick(tab, tabName, event) {
         if (tab.disabled) return;
         this.setCurrentName(tabName);
@@ -87,21 +98,9 @@
         } else {
           changeCurrentName();
         }
-      },
-      addPanes(item) {
-        const index = this.$slots.default.filter(item => {
-          return item.elm.nodeType === 1 && /\bel-tab-pane\b/.test(item.elm.className) || item.elm.nodeType === 8;
-        }).indexOf(item.$vnode);
-        this.panes.splice(index, 0, item);
-      },
-      removePanes(item) {
-        const panes = this.panes;
-        const index = panes.indexOf(item);
-        if (index > -1) {
-          panes.splice(index, 1);
-        }
       }
     },
+
     render(h) {
       let {
         type,
@@ -164,10 +163,19 @@
         </div>
       );
     },
+  
     created() {
       if (!this.currentName) {
         this.setCurrentName('0');
       }
+    },
+
+    mounted() {
+      this.calcPaneInstances();
+    },
+
+    updated() {
+      this.calcPaneInstances();
     }
   };
 </script>

+ 8 - 8
test/unit/specs/tabs.spec.js

@@ -223,19 +223,19 @@ describe('Tabs', () => {
       const paneList = vm.$el.querySelector('.el-tabs__content').children;
 
       tabList[1].querySelector('.el-icon-close').click();
-      vm.$nextTick(_ => {
+      setTimeout(_ => {
         expect(tabList.length).to.be.equal(2);
         expect(paneList.length).to.be.equal(2);
         expect(tabList[1].classList.contains('is-active')).to.be.true;
 
         vm.$refs.tabs.$el.querySelector('.el-tabs__new-tab').click();
-        vm.$nextTick(_ => {
+        setTimeout(_ => {
           expect(tabList.length).to.be.equal(3);
           expect(paneList.length).to.be.equal(3);
           expect(tabList[2].classList.contains('is-active')).to.be.true;
           done();
-        });
-      });
+        }, 100);
+      }, 100);
     }, 100);
   });
   it('addable & closable', done => {
@@ -310,19 +310,19 @@ describe('Tabs', () => {
 
       vm.$refs.tabs.$el.querySelector('.el-tabs__new-tab').click();
 
-      vm.$nextTick(_ => {
+      setTimeout(_ => {
         expect(tabList.length).to.be.equal(3);
         expect(paneList.length).to.be.equal(3);
         expect(tabList[2].classList.contains('is-active')).to.be.true;
 
         tabList[2].querySelector('.el-icon-close').click();
-        vm.$nextTick(_ => {
+        setTimeout(_ => {
           expect(tabList.length).to.be.equal(2);
           expect(paneList.length).to.be.equal(2);
           expect(tabList[1].classList.contains('is-active')).to.be.true;
           done();
-        });
-      });
+        }, 100);
+      }, 100);
     }, 100);
   });
   it('closable in tab-pane', (done) => {