浏览代码

[frontend] Tab selection not working after Vue3 migration, fixed it

sreenaths 4 年之前
父节点
当前提交
f8f4d095ea

+ 2 - 1
desktop/core/src/desktop/js/components/Tab.test.ts

@@ -29,7 +29,8 @@ describe('Tab.vue', () => {
           },
           removeTab: () => {
             // Empty
-          }
+          },
+          selectedTabRef: null
         }
       },
       slots: {

+ 26 - 26
desktop/core/src/desktop/js/components/Tab.vue

@@ -17,21 +17,22 @@
 -->
 
 <template>
-  <div v-if="!lazy || rendered" v-show="def.isActive">
+  <div v-if="!lazy || rendered" v-show="isActive">
     <slot />
   </div>
 </template>
 
 <script lang="ts">
   import { defineComponent, inject } from 'vue';
+  import { SELECTED_TAB_KEY, ADD_TAB_KEY, REMOVE_TAB_KEY } from './Tabs.vue';
 
   export interface TabRef {
     title: string;
-    isActive: boolean;
   }
 
   export default defineComponent({
     name: 'Tab',
+
     props: {
       title: {
         type: String,
@@ -43,47 +44,46 @@
       }
     },
 
-    setup(
-      props
-    ): {
-      addTab?: (tab: TabRef) => void;
-      removeTab?: (tab: TabRef) => void;
+    setup(props) {
+      const addTab: ((tab: TabRef) => void) | undefined = inject(ADD_TAB_KEY);
+      const removeTab: ((tab: TabRef) => void) | undefined = inject(REMOVE_TAB_KEY);
+
+      const selectedTabRef: TabRef | undefined = inject(SELECTED_TAB_KEY);
 
-      def: TabRef;
-    } {
       return {
-        addTab: inject('addTab'),
-        removeTab: inject('removeTab'),
+        addTab,
+        removeTab,
+        selectedTabRef,
 
-        def: {
-          title: props.title,
-          isActive: false
+        ref: {
+          title: props.title
         }
       };
     },
 
-    data(): {
-      rendered: boolean;
-    } {
+    data() {
       return {
         rendered: false
       };
     },
 
-    created() {
-      this.$watch(
-        (): boolean => this.def.isActive,
-        (isActive: boolean): void => {
-          if (isActive) {
-            this.rendered = true;
-          }
+    computed: {
+      isActive(): boolean {
+        return this.ref.title === this.selectedTabRef?.title;
+      }
+    },
+
+    watch: {
+      selectedTabRef(): void {
+        if (this.isActive) {
+          this.rendered = true;
         }
-      );
+      }
     },
 
     mounted(): void {
       if (this.addTab) {
-        this.addTab(this.def);
+        this.addTab(this.ref);
       }
     }
 

+ 35 - 36
desktop/core/src/desktop/js/components/Tabs.vue

@@ -22,8 +22,8 @@
       <li
         v-for="tab in tabs"
         :key="tab.title"
-        :class="{ active: tab.isActive }"
-        @click="selectTab(tab)"
+        :class="{ active: selectedTabRef === tab }"
+        @click="selectedTabRef = tab"
       >
         {{ tab.title }}
       </li>
@@ -35,51 +35,50 @@
 </template>
 
 <script lang="ts">
-  import { defineComponent } from 'vue';
+  import { defineComponent, ref, provide } from 'vue';
 
   import { TabRef } from './Tab.vue';
 
+  export const ADD_TAB_KEY = 'addTab';
+  export const REMOVE_TAB_KEY = 'removeTab';
+
+  export const SELECTED_TAB_KEY = 'selectedTabRef';
+
   export default defineComponent({
     name: 'Tabs',
-    provide(): {
-      addTab: (tab: TabRef) => void;
-      removeTab: (tab: TabRef) => void;
-    } {
-      return {
-        addTab: (tab: TabRef): void => {
-          if (!this.tabs.find(t => t.title === tab.title)) {
-            this.tabs.push(tab);
-            if (this.tabs.length === 1) {
-              this.selectTab(this.tabs[0]);
-            }
+
+    setup() {
+      const tabs = ref<TabRef[]>([]);
+      const selectedTabRef = ref<TabRef | null>(null);
+
+      function addTab(tab: TabRef): void {
+        if (!tabs.value.find(t => t.title === tab.title)) {
+          tabs.value.push(tab);
+          if (tabs.value.length === 1) {
+            selectedTabRef.value = tabs.value[0];
           }
-        },
-        removeTab: (tab: TabRef): void => {
-          const index = this.tabs.indexOf(tab);
-          if (index !== -1) {
-            this.tabs.splice(index, 1);
-            if (tab.isActive && this.tabs.length) {
-              this.tabs[Math.max(0, index - 1)].isActive = true;
-            }
+        }
+      }
+
+      function removeTab(tab: TabRef): void {
+        const index = tabs.value.indexOf(tab);
+        if (index !== -1) {
+          tabs.value.splice(index, 1);
+          if (tab === selectedTabRef.value && tabs.value.length) {
+            selectedTabRef.value = tabs.value[Math.max(0, index - 1)];
           }
         }
-      };
-    },
+      }
+
+      provide(ADD_TAB_KEY, (tab: TabRef) => addTab(tab));
+      provide(REMOVE_TAB_KEY, (tab: TabRef) => removeTab(tab));
+
+      provide(SELECTED_TAB_KEY, selectedTabRef);
 
-    data(): {
-      tabs: TabRef[];
-    } {
       return {
-        tabs: []
+        tabs,
+        selectedTabRef
       };
-    },
-
-    methods: {
-      selectTab(tab: TabRef): void {
-        this.tabs.forEach(other => {
-          other.isActive = other === tab;
-        });
-      }
     }
   });
 </script>

+ 1 - 3
desktop/core/src/desktop/js/components/__snapshots__/Tabs.test.ts.snap

@@ -40,9 +40,7 @@ exports[`Tabs.vue should render tabs 1`] = `
   >
     
     
-    <div
-      style="display: none;"
-    >
+    <div>
       
       foo