Browse Source

fix: Divider、ImagePreview、Pagination 组件优化与问题修复 (#1705)

* docs(divider): 文档样例修改

* fix(imagepreview): 组件优化

* fix(pagination): 修复参数为 string 时的显示错误问题

* fix(pagination): 回滚 demo
peixinyu 3 years ago
parent
commit
825514f3be

+ 15 - 27
src/packages/__VUE/divider/doc.en-US.md

@@ -25,9 +25,7 @@ Default render one horizontal divider line.
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider />
-    </nut-cell>
+  <nut-divider />
 </template>
 ```
 
@@ -41,9 +39,7 @@ Insert text into divider with default slot.
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider>text</nut-divider>
-    </nut-cell>
+  <nut-divider>text</nut-divider>
 </template>
 ```
 
@@ -57,12 +53,8 @@ Set Content Position with content-position attribute.
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider content-position="left">text</nut-divider>
-    </nut-cell>
-    <nut-cell>
-        <nut-divider content-position="right">text</nut-divider>
-    </nut-cell>
+  <nut-divider content-position="left">text</nut-divider>
+  <nut-divider content-position="right">text</nut-divider>
 </template>
 ```
 
@@ -77,9 +69,7 @@ Render dashed divider line with dashed attribute.
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider dashed>text</nut-divider>
-    </nut-cell>
+  <nut-divider dashed>text</nut-divider>
 </template>
 ```
 
@@ -93,9 +83,7 @@ User can custom divider style with style attribute.
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px' }">text</nut-divider>
-    </nut-cell>
+  <nut-divider :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px' }">text</nut-divider>
 </template>
 ```
 
@@ -107,15 +95,15 @@ User can custom divider style with style attribute.
 
 ``` html
 <template>
-    <nut-cell>
-        <div :style="{fontSize: '14px'}">
-            Text
-            <nut-divider direction="vertical" />
-            <a href="#" :style="{ color: '#1989fa' }">Link</a>
-            <nut-divider direction="vertical" />
-            <a href="#" :style="{ color: '#1989fa' }">Link</a>
-        </div>
-    </nut-cell>
+  <nut-cell>
+    <div :style="{fontSize: '14px'}">
+      Text
+      <nut-divider direction="vertical" />
+      <a href="#" :style="{ color: '#1989fa' }">Link</a>
+      <nut-divider direction="vertical" />
+      <a href="#" :style="{ color: '#1989fa' }">Link</a>
+    </div>
+  </nut-cell>
 </template>
 ```
 

+ 15 - 27
src/packages/__VUE/divider/doc.md

@@ -27,9 +27,7 @@ app.use(Divider);
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider />
-    </nut-cell>
+  <nut-divider />
 </template>
 ```
 
@@ -43,9 +41,7 @@ app.use(Divider);
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider>文本</nut-divider>
-    </nut-cell>
+  <nut-divider>文本</nut-divider>
 </template>
 ```
 
@@ -59,12 +55,8 @@ app.use(Divider);
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider content-position="left">文本</nut-divider>
-    </nut-cell>
-    <nut-cell>
-        <nut-divider content-position="right">文本</nut-divider>
-    </nut-cell>
+  <nut-divider content-position="left">文本</nut-divider>
+  <nut-divider content-position="right">文本</nut-divider>
 </template>
 ```
 
@@ -78,9 +70,7 @@ app.use(Divider);
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider dashed>文本</nut-divider>
-    </nut-cell>
+  <nut-divider dashed>文本</nut-divider>
 </template>
 ```
 
@@ -94,9 +84,7 @@ app.use(Divider);
 
 ``` html
 <template>
-    <nut-cell>
-        <nut-divider :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px' }">文本</nut-divider>
-    </nut-cell>
+  <nut-divider :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px' }">文本</nut-divider>
 </template>
 ```
 
@@ -108,15 +96,15 @@ app.use(Divider);
 
 ``` html
 <template>
-    <nut-cell>
-        <div :style="{fontSize: '14px'}">
-            文本
-            <nut-divider direction="vertical" />
-            <a href="#" :style="{ color: '#1989fa' }">链接</a>
-            <nut-divider direction="vertical" />
-            <a href="#" :style="{ color: '#1989fa' }">链接</a>
-        </div>
-    </nut-cell>
+  <nut-cell>
+    <div :style="{fontSize: '14px'}">
+      文本
+      <nut-divider direction="vertical" />
+      <a href="#" :style="{ color: '#1989fa' }">链接</a>
+      <nut-divider direction="vertical" />
+      <a href="#" :style="{ color: '#1989fa' }">链接</a>
+    </div>
+  </nut-cell>
 </template>
 ```
 

+ 3 - 2
src/packages/__VUE/imagepreview/doc.md

@@ -8,9 +8,10 @@
 
 ```javascript
 import { createApp, reactive, toRefs } from 'vue';
-
+//vue
 import { ImagePreview } from '@nutui/nutui';
-
+//taro
+import { ImagePreview } from '@nutui/nutui-taro';
 
 const app = createApp();
 app.use(ImagePreview);

+ 11 - 11
src/packages/__VUE/imagepreview/imagePreviewItem.vue

@@ -4,22 +4,22 @@
       <img :src="image.src" class="nut-imagepreview-img" @load="imageLoad" />
     </view>
 
-    <view class="nut-imagepreview-box" v-if="video">
+    <view class="nut-imagepreview-box" v-if="video && video.source">
       <nut-video :source="video.source" :options="video.options"></nut-video>
     </view>
   </nut-swiper-item>
 </template>
 <script lang="ts">
-import { toRefs, reactive, watch, onMounted, ref, computed, CSSProperties } from 'vue';
+import { toRefs, reactive, watch, computed, CSSProperties, PropType } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import Popup from '../popup/index.vue';
 import Video from '../video/index.vue';
 import Swiper from '../swiper/index.vue';
 import SwiperItem from '../swiperitem/index.vue';
 import Icon from '../icon/index.vue';
-import { isPromise } from '@/packages/utils/util.ts';
 import { useTouch } from '@/packages/utils/useTouch';
-const { componentName, create } = createComponent('imagepreviewitem');
+import { ImageInterface } from './types';
+const { create } = createComponent('imagepreviewitem');
 
 export default create({
   props: {
@@ -29,12 +29,12 @@ export default create({
     },
     initNo: Number,
     image: {
-      type: Object,
-      default: () => {}
+      type: Object as PropType<ImageInterface>,
+      default: () => ({})
     },
     video: {
-      type: Array,
-      default: () => {}
+      type: Object,
+      default: () => ({})
     },
 
     showIndex: {
@@ -126,7 +126,7 @@ export default create({
     });
 
     // 图片加载完成
-    const imageLoad = (event: any) => {
+    const imageLoad = (event: TouchEvent) => {
       const { naturalWidth, naturalHeight } = event.target as HTMLImageElement;
       state.imageRatio = naturalHeight / naturalWidth;
     };
@@ -165,7 +165,7 @@ export default create({
     let startMoveY: number;
     let startScale: number;
     let startDistance: number;
-    let doubleTapTimer: null;
+    let doubleTapTimer: number | null;
     let touchStartTime: number;
     let fingerNum: number;
 
@@ -279,7 +279,7 @@ export default create({
     };
 
     // 阻止
-    const preventDefault = (event: any, isStopPropagation?: boolean) => {
+    const preventDefault = (event: Event, isStopPropagation?: boolean) => {
       if (typeof event.cancelable !== 'boolean' || event.cancelable) {
         event.preventDefault();
       }

+ 18 - 22
src/packages/__VUE/imagepreview/index.taro.vue

@@ -28,15 +28,15 @@
   </nut-popup>
 </template>
 <script lang="ts">
-import { toRefs, reactive, watch, onMounted, computed } from 'vue';
+import { toRefs, reactive, watch, onMounted, computed, CSSProperties, PropType } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import Popup from '../popup/index.taro.vue';
-// import Video from '../video/index.vue';
 import Swiper from '../swiper/index.taro.vue';
 import SwiperItem from '../swiperitem/index.taro.vue';
 import Icon from '../icon/index.taro.vue';
-import { isPromise } from '@/packages/utils/util.ts';
-const { componentName, create } = createComponent('imagepreview');
+import { isPromise } from '@/packages/utils/util';
+import { ImageInterface } from './types';
+const { create } = createComponent('imagepreview');
 
 export default create({
   props: {
@@ -45,13 +45,9 @@ export default create({
       default: false
     },
     images: {
-      type: Array,
+      type: Array as PropType<ImageInterface[]>,
       default: () => []
     },
-    // videos: {
-    //   type: Array,
-    //   default: () => []
-    // },
     contentClose: {
       type: Boolean,
       default: false
@@ -100,8 +96,6 @@ export default create({
   },
 
   setup(props, { emit }) {
-    const { show, images } = toRefs(props);
-
     const state = reactive({
       showPop: false,
       active: 1,
@@ -114,16 +108,18 @@ export default create({
         muted: true,
         controls: true
       },
-      eleImg: null,
+      eleImg: null as HTMLElement | null,
       store: {
         scale: 1,
-        moveable: false
+        moveable: false,
+        originScale: 1,
+        oriDistance: 1
       },
       lastTouchEndTime: 0 // 用来辅助监听双击
     });
 
     const styles = computed(() => {
-      let style = {};
+      let style: CSSProperties = {};
       if (props.closeIconPosition == 'top-right') {
         style.right = '10px';
       } else {
@@ -171,7 +167,7 @@ export default create({
     };
 
     // 计算两个点的距离
-    const getDistance = (first: any, second: any) => {
+    const getDistance = (first: { x: number; y: number }, second: { x: number; y: number }) => {
       // 计算两个点起始时刻的距离和终止时刻的距离,终止时刻距离变大了则放大,变小了则缩小
       // 放大 k 倍则 scale 也 扩大 k 倍
       return Math.hypot(Math.abs(second.x - first.x), Math.abs(second.y - first.y));
@@ -179,11 +175,11 @@ export default create({
 
     const scaleNow = () => {
       if (state.eleImg != null) {
-        (state.eleImg as any).style.transform = 'scale(' + state.store.scale + ')';
+        state.eleImg.style.transform = 'scale(' + state.store.scale + ')';
       }
     };
 
-    const onTouchStart = (event: any) => {
+    const onTouchStart = (event: TouchEvent) => {
       // console.log('start');
       // 如果已经放大,双击应变回原尺寸;如果是原尺寸,双击应放大
       const curTouchTime = new Date().getTime();
@@ -203,7 +199,7 @@ export default create({
 
       // event.preventDefault();
 
-      const store = state.store as any;
+      const store = state.store;
       store.moveable = true;
 
       if (events2) {
@@ -223,11 +219,11 @@ export default create({
       store.originScale = store.scale || 1;
     };
 
-    const onTouchMove = (event: any) => {
+    const onTouchMove = (event: TouchEvent) => {
       if (!state.store.moveable) {
         return;
       }
-      const store = state.store as any;
+      const store = state.store;
       // event.preventDefault();
       var touches = event.touches;
       var events = touches[0];
@@ -264,7 +260,7 @@ export default create({
     const onTouchEnd = () => {
       // console.log('end');
       state.lastTouchEndTime = new Date().getTime();
-      const store = state.store as any;
+      const store = state.store;
       store.moveable = false;
       if ((store.scale < 1.1 && store.scale > 1) || store.scale < 1) {
         store.scale = 1;
@@ -273,7 +269,7 @@ export default create({
     };
 
     const init = () => {
-      state.eleImg = document.querySelector('.nut-imagepreview') as any;
+      state.eleImg = document.querySelector('.nut-imagepreview');
       document.addEventListener('touchmove', onTouchMove);
       document.addEventListener('touchend', onTouchEnd);
       document.addEventListener('touchcancel', onTouchEnd);

+ 10 - 10
src/packages/__VUE/imagepreview/index.ts

@@ -1,13 +1,13 @@
 import ImagePreview from './index.vue';
-import { render, createVNode, h } from 'vue';
+import { render, createVNode, h, VNode } from 'vue';
 import { ImageInterface } from './types';
 export class ImagePreviewOptions {
-  show: Boolean = false;
+  show = false;
   images: ImageInterface[] = [];
-  initNo: Number = 1;
-  paginationVisible: Boolean = false;
-  paginationColor: string = '';
-  teleport: String | HTMLElement = 'body';
+  initNo = 1;
+  paginationVisible = false;
+  paginationColor = '';
+  teleport: string | HTMLElement = 'body';
 
   // function
   onClose?: Function = () => {};
@@ -17,9 +17,9 @@ class ImagePreviewFunction {
   options: ImagePreviewOptions = new ImagePreviewOptions();
 
   constructor(_options: ImagePreviewOptions) {
-    let options = Object.assign(this.options, _options);
+    const options = Object.assign(this.options, _options);
     let elWarp: HTMLElement = document.body;
-    let teleport = options.teleport as string;
+    const teleport = options.teleport as string;
     if (teleport != 'body') {
       if (typeof teleport == 'string') {
         elWarp = document.querySelector(teleport) as HTMLElement;
@@ -40,13 +40,13 @@ class ImagePreviewFunction {
         };
       }
     };
-    const instance: any = createVNode(Wrapper);
+    const instance: VNode = createVNode(Wrapper);
     elWarp.appendChild(root);
     render(instance, root);
   }
 }
 
-const _ImagePreview = function (options: ImagePreviewOptions) {
+const _ImagePreview = (options: ImagePreviewOptions): ImagePreviewFunction => {
   return new ImagePreviewFunction(options);
 };
 _ImagePreview.install = (app: any) => {

+ 5 - 6
src/packages/__VUE/imagepreview/index.vue

@@ -5,6 +5,7 @@
     :isWrapTeleport="isWrapTeleport"
     @click="onClose"
     style="width: 100%"
+    lock-scroll
   >
     <!-- @click.stop="closeOnImg" @touchstart.capture="onTouchStart" -->
     <view class="nut-imagepreview" ref="swipeRef">
@@ -54,7 +55,7 @@
   </nut-popup>
 </template>
 <script lang="ts">
-import { toRefs, reactive, watch, onMounted, ref, computed } from 'vue';
+import { toRefs, reactive, watch, onMounted, ref, computed, CSSProperties } from 'vue';
 import type { PropType } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 import Popup from '../popup/index.vue';
@@ -62,10 +63,10 @@ import Video from '../video/index.vue';
 import Swiper from '../swiper/index.vue';
 import SwiperItem from '../swiperitem/index.vue';
 import Icon from '../icon/index.vue';
-import { isPromise } from '@/packages/utils/util.ts';
+import { isPromise } from '@/packages/utils/util';
 import ImagePreviewItem from './imagePreviewItem.vue';
 import { ImageInterface } from './types';
-const { componentName, create } = createComponent('imagepreview');
+const { create } = createComponent('imagepreview');
 
 export default create({
   props: {
@@ -142,8 +143,6 @@ export default create({
   },
 
   setup(props, { emit }) {
-    const { show, images } = toRefs(props);
-
     const swipeRef = ref();
 
     const state = reactive({
@@ -155,7 +154,7 @@ export default create({
     });
 
     const styles = computed(() => {
-      let style: any = {};
+      let style: CSSProperties = {};
       if (props.closeIconPosition == 'top-right') {
         style.right = '10px';
       } else {

+ 2 - 2
src/packages/__VUE/pagination/demo.vue

@@ -22,7 +22,7 @@
 </template>
 
 <script lang="ts">
-import { ref, reactive, toRefs } from 'vue';
+import { reactive, toRefs } from 'vue';
 import { createComponent } from '@/packages/utils/create';
 const { createDemo, translate } = createComponent('pagination');
 import { useTranslate } from '@/sites/assets/util/useTranslate';
@@ -51,7 +51,7 @@ export default createDemo({
       currentPage3: 1
     });
     const pageChange = (value: number) => {
-      console.log(value);
+      console.log('page change', value);
     };
 
     return {

+ 9 - 8
src/packages/__VUE/pagination/index.taro.vue

@@ -34,9 +34,9 @@
   </view>
 </template>
 <script lang="ts">
-import { toRefs, onMounted, watchEffect, computed } from 'vue';
+import { toRefs, watchEffect, computed } from 'vue';
 import { createComponent } from '@/packages/utils/create';
-const { componentName, create, translate } = createComponent('pagination');
+const { create, translate } = createComponent('pagination');
 
 export default create({
   props: {
@@ -78,6 +78,7 @@ export default create({
     }
   },
   components: {},
+
   emits: ['change', 'update:modelValue'],
 
   setup(props, { emit }) {
@@ -91,31 +92,31 @@ export default create({
     });
 
     //点击选择page
-    const select = (curPage, isSelect) => {
+    const select = (curPage: number, isSelect: boolean) => {
       if (curPage > countRef.value || curPage < 1) return;
       if (curPage != modelValue.value) emit('update:modelValue', curPage);
       if (isSelect) emit('change', curPage);
     };
     //set page 对象
-    const setPage = (number, text, active) => {
+    const setPage = (number: number, text: string | number, active = false) => {
       return { number, text, active };
     };
     //生成pages数组,用来遍历
     const pages = computed(() => {
+      if (mode.value == 'simple') return;
       let items = [];
       const pageCount = countRef.value; //总的页面数量
-      const pageSize = showPageSize.value; //展示的页面个数
+      const pageSize = +showPageSize.value; //展示的页面个数
       let startPage = 1;
       let endPage = pageCount;
-      if (mode.value == 'simple') return;
       const partialShow = pageCount > pageSize;
       if (partialShow) {
         //选中的page在展示的page中间
         startPage = Math.max(modelValue.value - Math.floor(pageSize / 2), 1);
-        endPage = startPage + pageSize - 1;
+        endPage = startPage + +pageSize - 1;
         if (endPage > pageCount) {
           endPage = pageCount;
-          startPage = endPage - pageSize + 1;
+          startPage = endPage - +pageSize + 1;
         }
       }
       //遍历生成数组

+ 7 - 7
src/packages/__VUE/pagination/index.vue

@@ -34,9 +34,9 @@
   </view>
 </template>
 <script lang="ts">
-import { toRefs, onMounted, watchEffect, computed } from 'vue';
+import { toRefs, watchEffect, computed } from 'vue';
 import { createComponent } from '@/packages/utils/create';
-const { componentName, create, translate } = createComponent('pagination');
+const { create, translate } = createComponent('pagination');
 
 export default create({
   props: {
@@ -92,13 +92,13 @@ export default create({
     });
 
     //点击选择page
-    const select = (curPage, isSelect) => {
+    const select = (curPage: number, isSelect: boolean) => {
       if (curPage > countRef.value || curPage < 1) return;
       if (curPage != modelValue.value) emit('update:modelValue', curPage);
       if (isSelect) emit('change', curPage);
     };
     //set page 对象
-    const setPage = (number, text, active) => {
+    const setPage = (number: number, text: string | number, active = false) => {
       return { number, text, active };
     };
     //生成pages数组,用来遍历
@@ -106,17 +106,17 @@ export default create({
       if (mode.value == 'simple') return;
       let items = [];
       const pageCount = countRef.value; //总的页面数量
-      const pageSize = showPageSize.value; //展示的页面个数
+      const pageSize = +showPageSize.value; //展示的页面个数
       let startPage = 1;
       let endPage = pageCount;
       const partialShow = pageCount > pageSize;
       if (partialShow) {
         //选中的page在展示的page中间
         startPage = Math.max(modelValue.value - Math.floor(pageSize / 2), 1);
-        endPage = startPage + pageSize - 1;
+        endPage = startPage + +pageSize - 1;
         if (endPage > pageCount) {
           endPage = pageCount;
-          startPage = endPage - pageSize + 1;
+          startPage = endPage - +pageSize + 1;
         }
       }
       //遍历生成数组