Browse Source

fix(tabs): the automatic scrolling fails while updating title bar data (#2017)

* feat(tabs): remove scroll method

* fix(tabs): automatic scrolling fails when updating

* docs(tabs): update description of name property

* refactor(tabs): rename inner data
gyt95 3 years ago
parent
commit
027b387dd8

+ 2 - 3
src/packages/__VUE/tabs/doc.en-US.md

@@ -173,7 +173,7 @@ export default {
 
 
 ### A large number of scrolling operations
 ### A large number of scrolling operations
 
 
-In the `taro` environment, when multiple `tabs` are included in the same page, `name` needs to be set as a unique identifier to enable the automatic scrolling function of the title bar.
+In the `taro` environment, `name` must be set to enable the automatic scrolling function of the title bar.
 
 
 :::demo
 :::demo
 ```html
 ```html
@@ -352,8 +352,7 @@ export default {
 | auto-height`v3.1.21` | Automatic height. When set to `true`, `nut-tabs` and `nut-tabs__content` will change with the height of the current `nut-tabpane`. | boolean       | false      |
 | auto-height`v3.1.21` | Automatic height. When set to `true`, `nut-tabs` and `nut-tabs__content` will change with the height of the current `nut-tabpane`. | boolean       | false      |
 | sticky`v3.2.3` `applet not supported` | Whether to use sticky mode| boolean       | false      |
 | sticky`v3.2.3` `applet not supported` | Whether to use sticky mode| boolean       | false      |
 | top`v3.2.3` `applet not supported` | Sticky offset top | number       | 0      |
 | top`v3.2.3` `applet not supported` | Sticky offset top | number       | 0      |
-| name        | In the `taro` environment, when multiple `tabs` are included in the same page, `name` needs to be set as a unique identifier to enable the automatic scrolling function of the title bar.                              | string | ''        |
-
+| name        | In the `taro` environment, `name` must be set to enable the automatic scrolling function of the title bar.                              | string | ''        |
 
 
 
 
 
 

+ 2 - 2
src/packages/__VUE/tabs/doc.md

@@ -173,7 +173,7 @@ export default {
 
 
 ### 数量多,滚动操作
 ### 数量多,滚动操作
 
 
-在`taro`环境下,当同一页面中包含多个`tabs`时,需要设置`name`作为唯一标识符来开启标题栏自动滚动功能。
+在`taro`环境下,必须设置`name`以开启标题栏自动滚动功能。
 
 
 :::demo
 :::demo
 ```html
 ```html
@@ -352,7 +352,7 @@ export default {
 | auto-height`v3.1.21` | 自动高度。设置为 true 时,nut-tabs 和 nut-tabs__content 会随着当前 nut-tabpane 的高度而发生变化。 | boolean       | false      |
 | auto-height`v3.1.21` | 自动高度。设置为 true 时,nut-tabs 和 nut-tabs__content 会随着当前 nut-tabpane 的高度而发生变化。 | boolean       | false      |
 | sticky`v3.2.3` `小程序不支持` | 是否使用粘性布局 | boolean       | false      |
 | sticky`v3.2.3` `小程序不支持` | 是否使用粘性布局 | boolean       | false      |
 | top`v3.2.3` `小程序不支持` | 粘性布局下的吸顶距离 | number       | 0      |
 | top`v3.2.3` `小程序不支持` | 粘性布局下的吸顶距离 | number       | 0      |
-| name        | 在`taro`环境下,当同一页面中包含多个`tabs`时,需要设置`name`作为唯一标识符来开启标题栏自动滚动功能。                              | string | ''        |
+| name        | 在`taro`环境下,必须设置`name`以开启标题栏自动滚动功能。                              | string | ''        |
 
 
 ### Tabs Slots
 ### Tabs Slots
 
 

+ 9 - 4
src/packages/__VUE/tabs/index.scss

@@ -194,8 +194,13 @@
 .tabs-scrollview {
 .tabs-scrollview {
   white-space: nowrap;
   white-space: nowrap;
 }
 }
-.nut-tabs__titles-item .taro {
-  display: inline-block !important;
-  height: 46px;
-  line-height: 46px;
+.nut-tabs__titles-item {
+  &.nut-tabs__titles-placeholder {
+    width: auto;
+    min-width: 10px;
+  }
+  .taro {
+    height: 46px;
+    line-height: 46px;
+  }
 }
 }

+ 25 - 16
src/packages/__VUE/tabs/index.taro.vue

@@ -9,7 +9,6 @@
       class="nut-tabs__titles tabs-scrollview"
       class="nut-tabs__titles tabs-scrollview"
       :class="{ [type]: type, scrollable: titleScroll, [size]: size }"
       :class="{ [type]: type, scrollable: titleScroll, [size]: size }"
       :style="tabsNavStyle"
       :style="tabsNavStyle"
-      @scroll="handleScroll"
     >
     >
       <slot v-if="$slots.titles" name="titles"></slot>
       <slot v-if="$slots.titles" name="titles"></slot>
       <template v-else>
       <template v-else>
@@ -27,6 +26,7 @@
           </view>
           </view>
           <view class="nut-tabs__titles-item__text" :class="{ ellipsis: ellipsis }">{{ item.title }} </view>
           <view class="nut-tabs__titles-item__text" :class="{ ellipsis: ellipsis }">{{ item.title }} </view>
         </view>
         </view>
+        <view v-if="canShowLabel" class="nut-tabs__titles-item nut-tabs__titles-placeholder"></view>
       </template>
       </template>
     </Nut-Scroll-View>
     </Nut-Scroll-View>
     <view class="nut-tabs__content" :style="contentStyle">
     <view class="nut-tabs__content" :style="contentStyle">
@@ -43,6 +43,7 @@ import NutScrollView from '../scrollView/index.taro.vue';
 import { onMounted, provide, VNode, ref, Ref, computed, onActivated, watch, nextTick } from 'vue';
 import { onMounted, provide, VNode, ref, Ref, computed, onActivated, watch, nextTick } from 'vue';
 import raf from '@/packages/utils/raf';
 import raf from '@/packages/utils/raf';
 import Taro from '@tarojs/taro';
 import Taro from '@tarojs/taro';
+import type { RectItem } from './types';
 export class Title {
 export class Title {
   title: string = '';
   title: string = '';
   titleSlot?: VNode[];
   titleSlot?: VNode[];
@@ -166,14 +167,13 @@ export default create({
 
 
     const titleRef = ref([]) as Ref<HTMLElement[]>;
     const titleRef = ref([]) as Ref<HTMLElement[]>;
     const scrollLeft = ref(0);
     const scrollLeft = ref(0);
-    const scrollWithAnimation = ref(true);
+    const scrollWithAnimation = ref(false);
     const getRect = (selector: string) => {
     const getRect = (selector: string) => {
       return new Promise((resolve) => {
       return new Promise((resolve) => {
         Taro.createSelectorQuery()
         Taro.createSelectorQuery()
           .select(selector)
           .select(selector)
           .boundingClientRect()
           .boundingClientRect()
           .exec((rect = []) => {
           .exec((rect = []) => {
-            console.log(rect);
             resolve(rect[0]);
             resolve(rect[0]);
           });
           });
       });
       });
@@ -186,24 +186,36 @@ export default create({
           .exec((rect = []) => resolve(rect[0]));
           .exec((rect = []) => resolve(rect[0]));
       });
       });
     };
     };
-    const inited = ref(false);
     const navRectRef = ref();
     const navRectRef = ref();
-    const titleRectRef = ref([]);
+    const titleRectRef = ref<RectItem[]>([]);
+    const canShowLabel = ref(false);
     const scrollIntoView = () => {
     const scrollIntoView = () => {
+      if (!props.name) return;
+
       raf(() => {
       raf(() => {
         Promise.all([
         Promise.all([
           getRect(`#nut-tabs__titles_${props.name}`),
           getRect(`#nut-tabs__titles_${props.name}`),
           getAllRect(`#nut-tabs__titles_${props.name} .nut-tabs__titles-item`)
           getAllRect(`#nut-tabs__titles_${props.name} .nut-tabs__titles-item`)
-        ]).then(([navRect, titleRects]) => {
-          if (!inited.value) {
-            navRectRef.value = navRect;
-            titleRectRef.value = titleRects;
-            inited.value = true;
+        ]).then(([navRect, titleRects]: any) => {
+          navRectRef.value = navRect;
+          titleRectRef.value = titleRects;
+
+          if (navRectRef.value) {
+            const titlesTotalWidth = titleRects.reduce((prev: number, curr: RectItem) => prev + curr.width, 0);
+            if (titlesTotalWidth > navRectRef.value.width) {
+              canShowLabel.value = true;
+            } else {
+              canShowLabel.value = false;
+            }
           }
           }
 
 
-          const titleRect = titleRectRef.value[currentIndex.value];
+          const titleRect: RectItem = titleRectRef.value[currentIndex.value];
 
 
-          let to = titleRect.left - (navRectRef.value.width - titleRect.width) / 2;
+          const left = titleRects
+            .slice(0, currentIndex.value)
+            .reduce((prev: number, curr: RectItem) => prev + curr.width + 20, 31);
+
+          const to = left - (navRectRef.value.width - titleRect.width) / 2;
 
 
           nextTick(() => {
           nextTick(() => {
             scrollWithAnimation.value = true;
             scrollWithAnimation.value = true;
@@ -310,9 +322,6 @@ export default create({
       }
       }
     };
     };
 
 
-    const handleScroll = (e: any) => {
-      console.log(e);
-    };
     return {
     return {
       titles,
       titles,
       contentStyle,
       contentStyle,
@@ -323,7 +332,7 @@ export default create({
       scrollLeft,
       scrollLeft,
       scrollWithAnimation,
       scrollWithAnimation,
       onStickyScroll,
       onStickyScroll,
-      handleScroll,
+      canShowLabel,
       ...methods
       ...methods
     };
     };
   }
   }

+ 10 - 0
src/packages/__VUE/tabs/types.ts

@@ -0,0 +1,10 @@
+export type RectItem = {
+  bottom: number;
+  dataset: { sid: string };
+  height: number;
+  id: string;
+  left: number;
+  right: number;
+  top: number;
+  width: number;
+};