Browse Source

fix(swiper): dynamic rendering error (#1155 #1249)

suzigang 3 years ago
parent
commit
a0a43d7fe2

+ 36 - 2
src/packages/__VUE/swiper/demo.vue

@@ -8,6 +8,14 @@
         </nut-swiper-item>
       </nut-swiper>
     </view>
+    <h2>{{ translate('asyc') }}</h2>
+    <view class="demo-box">
+      <nut-swiper :init-page="page" :pagination-visible="true" pagination-color="#426543" auto-play="2000">
+        <nut-swiper-item v-for="item in list1" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+      </nut-swiper>
+    </view>
     <h2>{{ translate('size') }}</h2>
     <view class="demo-box">
       <nut-swiper :init-page="page2" :loop="false" width="300">
@@ -27,6 +35,17 @@
         </template>
       </nut-swiper>
     </view>
+    <h2>{{ translate('indicator1') }}</h2>
+    <view class="demo-box">
+      <nut-swiper :init-page="page" :loop="true" @change="change1" auto-play="2000">
+        <nut-swiper-item v-for="item in list1" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+        <template v-slot:page>
+          <div class="page"> {{ current1 }}/4 </div>
+        </template>
+      </nut-swiper>
+    </view>
     <h2>{{ translate('vertical') }}</h2>
     <view class="demo-box">
       <nut-swiper
@@ -47,21 +66,25 @@
 </template>
 
 <script lang="ts">
-import { reactive, toRefs } from 'vue';
+import { reactive, toRefs, onMounted } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { createDemo, translate } = createComponent('swiper');
 import { useTranslate } from '@/sites/assets/util/useTranslate';
 useTranslate({
   'zh-CN': {
     basic: '基本用法',
+    asyc: '异步加载(3s)',
     size: '自定义大小',
     indicator: '自定义指示器',
+    indicator1: '自定义指示器(异步3s)',
     vertical: '垂直方向'
   },
   'en-US': {
     basic: 'Basic Usage',
+    asyc: 'Asynchronous loading(3s)',
     size: 'Custom size',
     indicator: 'Custom indicator',
+    indicator1: 'Custom indicator(Asynchronous loading(3s))',
     vertical: 'Vertical direction'
   }
 });
@@ -74,19 +97,30 @@ export default createDemo({
       page3: 0,
       page4: 0,
       current: 1,
+      current1: 3,
       list: [
         'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
         'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
         'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
         'https://storage.360buyimg.com/jdc-article/fristfabu.jpg'
-      ]
+      ],
+      list1: [] as string[]
     });
     const change = (index: number) => {
       state.current = index + 1;
     };
+    const change1 = (index: number) => {
+      state.current1 = index + 1;
+    };
+    onMounted(() => {
+      setTimeout(() => {
+        state.list1 = state.list.slice();
+      }, 3000);
+    });
     return {
       ...toRefs(state),
       change,
+      change1,
       translate
     };
   }

+ 47 - 0
src/packages/__VUE/swiper/doc.en-US.md

@@ -67,6 +67,53 @@ app.use(Swiper).use(SwiperItem);
 
 :::
 
+### Asynchronous loading
+
+:::demo
+
+```html
+<template>
+  <nut-swiper :init-page="page" :pagination-visible="true" pagination-color="#426543" auto-play="3000">
+     <nut-swiper-item v-for="item in list" :key="item">
+        <img :src="item" alt="" />
+      </nut-swiper-item>
+  </nut-swiper>
+</template>
+<script lang="ts">
+  import { reactive, toRefs, onMounted } from 'vue';
+  export default {
+    setup() {
+      const state = reactive({
+        page: 2,
+        list: [] as string[]
+      });
+      onMounted(() => {
+        setTimeout(() => {
+          state.list = [
+            'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
+            'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
+            'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
+            'https://storage.360buyimg.com/jdc-article/fristfabu.jpg'
+          ];
+        }, 3000);
+      });
+      return { ...toRefs(state) };
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .nut-swiper-item {
+    line-height: 150px;
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>
+```
+
+:::
+
 ### Custom size
 
 `width` Custom rotation size

+ 47 - 0
src/packages/__VUE/swiper/doc.md

@@ -67,6 +67,53 @@ app.use(Swiper).use(SwiperItem);
 
 :::
 
+### 异步加载
+
+:::demo
+
+```html
+<template>
+  <nut-swiper :init-page="page" :pagination-visible="true" pagination-color="#426543" auto-play="3000">
+     <nut-swiper-item v-for="item in list" :key="item">
+        <img :src="item" alt="" />
+      </nut-swiper-item>
+  </nut-swiper>
+</template>
+<script lang="ts">
+  import { reactive, toRefs, onMounted } from 'vue';
+  export default {
+    setup() {
+      const state = reactive({
+        page: 2,
+        list: [] as string[]
+      });
+      onMounted(() => {
+        setTimeout(() => {
+          state.list = [
+            'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
+            'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
+            'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
+            'https://storage.360buyimg.com/jdc-article/fristfabu.jpg'
+          ];
+        }, 3000);
+      });
+      return { ...toRefs(state) };
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .nut-swiper-item {
+    line-height: 150px;
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>
+```
+
+:::
+
 ### 自定义大小
 
 `width` 自定义轮播大小

+ 20 - 37
src/packages/__VUE/swiper/index.taro.vue

@@ -38,8 +38,6 @@
 
 <script lang="ts">
 import {
-  onMounted,
-  onActivated,
   onDeactivated,
   onBeforeUnmount,
   provide,
@@ -47,7 +45,6 @@ import {
   ComponentPublicInstance,
   reactive,
   computed,
-  nextTick,
   ref,
   watch
 } from 'vue';
@@ -55,7 +52,7 @@ import { createComponent } from '@/packages/utils/create';
 import { useTouch } from './use-touch';
 import { useTaroRect } from '@/packages/utils/useTaroRect';
 import { useExpose } from '@/packages/utils/useExpose/index';
-import Taro, { eventCenter, getCurrentInstance, useReady } from '@tarojs/taro';
+import Taro, { eventCenter, getCurrentInstance } from '@tarojs/taro';
 const { create, componentName } = createComponent('swiper');
 export default create({
   props: {
@@ -319,15 +316,17 @@ export default create({
     const init = async (active: number = +props.initPage) => {
       stopAutoPlay();
       state.rect = await useTaroRect(container, Taro);
-      active = Math.min(childCount.value - 1, active);
-      state.width = props.width ? +props.width : (state.rect as DOMRect).width;
-      state.height = props.height ? +props.height : (state.rect as DOMRect).height;
-      state.active = active;
-      state.offset = getOffset(state.active);
-      state.moving = true;
-      getStyle();
+      if (state.rect) {
+        active = Math.min(childCount.value - 1, active);
+        state.width = props.width ? +props.width : (state.rect as DOMRect).width;
+        state.height = props.height ? +props.height : (state.rect as DOMRect).height;
+        state.active = active;
+        state.offset = getOffset(state.active);
+        state.moving = true;
+        getStyle();
 
-      autoplay();
+        autoplay();
+      }
     };
 
     const onTouchStart = (e: TouchEvent) => {
@@ -388,30 +387,6 @@ export default create({
       to
     });
 
-    onMounted(() => {
-      if (Taro.getEnv() === 'WEB') {
-        init();
-      } else {
-        Taro.nextTick(async () => {
-          state.rect = await useTaroRect(container, Taro);
-          state.rect && init();
-        });
-        eventCenter.once((getCurrentInstance() as any).router.onReady, () => {
-          init();
-        });
-      }
-    });
-
-    onActivated(() => {
-      if (Taro.getEnv() === 'WEB') {
-        init();
-      } else {
-        eventCenter.once((getCurrentInstance() as any).router.onReady, () => {
-          init();
-        });
-      }
-    });
-
     onDeactivated(() => {
       stopAutoPlay();
     });
@@ -423,6 +398,9 @@ export default create({
     watch(
       () => props.initPage,
       (val) => {
+        Taro.nextTick(() => {
+          init(+val);
+        });
         eventCenter.once((getCurrentInstance() as any).router.onReady, () => {
           init(+val);
         });
@@ -432,8 +410,13 @@ export default create({
     watch(
       () => state.children.length,
       () => {
+        Taro.nextTick(() => {
+          init();
+        });
         eventCenter.once((getCurrentInstance() as any).router.onReady, () => {
-          init(state.active);
+          Taro.nextTick(() => {
+            init();
+          });
         });
       }
     );

+ 2 - 13
src/packages/__VUE/swiper/index.vue

@@ -384,18 +384,6 @@ export default create({
       to
     });
 
-    onMounted(() => {
-      nextTick(() => {
-        init();
-      });
-    });
-
-    onActivated(() => {
-      nextTick(() => {
-        init();
-      });
-    });
-
     onDeactivated(() => {
       stopAutoPlay();
     });
@@ -417,7 +405,8 @@ export default create({
       () => state.children.length,
       () => {
         nextTick(() => {
-          init(state.active);
+          // console.log(state.active)
+          init();
         });
       }
     );

+ 32 - 2
src/sites/mobile-taro/vue/src/exhibition/pages/swiper/index.vue

@@ -8,6 +8,14 @@
         </nut-swiper-item>
       </nut-swiper>
     </view>
+    <h2>异步加载(3s)</h2>
+    <view class="demo-box">
+      <nut-swiper :init-page="page" :pagination-visible="true" pagination-color="#426543" auto-play="2000">
+        <nut-swiper-item v-for="item in list1" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+      </nut-swiper>
+    </view>
     <h2>自定义大小</h2>
     <view class="demo-box">
       <nut-swiper :init-page="page2" :loop="false" width="300">
@@ -27,6 +35,17 @@
         </template>
       </nut-swiper>
     </view>
+    <h2>自定义指示器(异步加载3s)</h2>
+    <view class="demo-box">
+      <nut-swiper :init-page="page" :loop="true" @change="change1" auto-play="2000">
+        <nut-swiper-item v-for="item in list1" :key="item">
+          <img :src="item" alt="" />
+        </nut-swiper-item>
+        <template v-slot:page>
+          <div class="page"> {{ current1 }}/4 </div>
+        </template>
+      </nut-swiper>
+    </view>
     <h2>垂直方向</h2>
     <view class="demo-box">
       <nut-swiper
@@ -58,19 +77,30 @@ export default {
       page3: 0,
       page4: 0,
       current: 1,
+      current1: 3,
       list: [
         'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
         'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
         'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
         'https://storage.360buyimg.com/jdc-article/fristfabu.jpg'
-      ]
+      ],
+      list1: [] as string[]
     });
     const change = (index: number) => {
       state.current = index + 1;
     };
+    const change1 = (index: number) => {
+      state.current1 = index + 1;
+    };
+    onMounted(() => {
+      setTimeout(() => {
+        state.list1 = state.list.slice();
+      }, 3000);
+    });
     return {
       ...toRefs(state),
-      change
+      change,
+      change1
     };
   }
 };