浏览代码

fix(range、uploader): taro h5 env bug #682

richard1015 4 年之前
父节点
当前提交
5f79419146

+ 10 - 22
src/packages/__VUE/range/index.taro.vue

@@ -1,13 +1,7 @@
 <template>
   <view class="nut-range-container">
     <view class="min" v-if="!hiddenRange">{{ +min }}</view>
-    <view
-      ref="root"
-      id="root"
-      :style="wrapperStyle"
-      :class="classes"
-      @click.stop="onClick"
-    >
+    <view ref="root" id="root" :style="wrapperStyle" :class="classes" @click.stop="onClick">
       <view class="nut-range-bar" :style="barStyle">
         <template v-if="range">
           <view
@@ -39,9 +33,7 @@
           >
             <slot v-if="$slots.button" name="button"></slot>
             <view class="nut-range-button" v-else :style="buttonStyle">
-              <view class="number" v-if="!hiddenTag">{{
-                curValue(index)
-              }}</view>
+              <view class="number" v-if="!hiddenTag">{{ curValue(index) }}</view>
             </view>
           </view>
         </template>
@@ -66,9 +58,7 @@
           >
             <slot v-if="$slots.button" name="button"></slot>
             <view class="nut-range-button" v-else :style="buttonStyle">
-              <view class="number" v-if="!hiddenTag">{{
-                curValue(index)
-              }}</view>
+              <view class="number" v-if="!hiddenTag">{{ curValue(index) }}</view>
             </view>
           </view>
         </template>
@@ -157,8 +147,7 @@ export default create({
       };
     });
 
-    const isRange = (val: unknown): val is number[] =>
-      !!props.range && Array.isArray(val);
+    const isRange = (val: unknown): val is number[] => !!props.range && Array.isArray(val);
 
     const calcMainAxis = () => {
       const { modelValue, min } = props;
@@ -223,7 +212,7 @@ export default create({
       }
 
       const { min, modelValue } = props;
-      let rect = await useTaroRect(root, Taro);
+      const rect = await useTaroRect(root, Taro);
       const delta = (event as any).touches[0].clientX - rect.left;
       const total = rect.width;
       const value = Number(min) + (delta / total) * scope.value;
@@ -275,12 +264,14 @@ export default create({
       const diff = (delta / total) * scope.value;
 
       if (isRange(startValue)) {
-        (currentValue as number[])[buttonIndex.value] =
-          startValue[buttonIndex.value] + diff;
+        (currentValue as number[])[buttonIndex.value] = startValue[buttonIndex.value] + diff;
       } else {
         currentValue = startValue + diff;
       }
       updateValue(currentValue);
+
+      event.stopPropagation();
+      event.preventDefault();
     };
 
     const onTouchEnd = () => {
@@ -295,10 +286,7 @@ export default create({
     };
 
     const curValue = (idx?: number) => {
-      const value =
-        typeof idx === 'number'
-          ? (props.modelValue as number[])[idx]
-          : props.modelValue;
+      const value = typeof idx === 'number' ? (props.modelValue as number[])[idx] : props.modelValue;
       return value;
     };
 

+ 8 - 20
src/packages/__VUE/range/index.vue

@@ -1,12 +1,7 @@
 <template>
   <view class="nut-range-container">
     <view class="min" v-if="!hiddenRange">{{ +min }}</view>
-    <view
-      ref="root"
-      :style="wrapperStyle"
-      :class="classes"
-      @click.stop="onClick"
-    >
+    <view ref="root" :style="wrapperStyle" :class="classes" @click.stop="onClick">
       <view class="nut-range-bar" :style="barStyle">
         <template v-if="range">
           <view
@@ -38,9 +33,7 @@
           >
             <slot v-if="$slots.button" name="button"></slot>
             <view class="nut-range-button" v-else :style="buttonStyle">
-              <view class="number" v-if="!hiddenTag">{{
-                curValue(index)
-              }}</view>
+              <view class="number" v-if="!hiddenTag">{{ curValue(index) }}</view>
             </view>
           </view>
         </template>
@@ -65,9 +58,7 @@
           >
             <slot v-if="$slots.button" name="button"></slot>
             <view class="nut-range-button" v-else :style="buttonStyle">
-              <view class="number" v-if="!hiddenTag">{{
-                curValue(index)
-              }}</view>
+              <view class="number" v-if="!hiddenTag">{{ curValue(index) }}</view>
             </view>
           </view>
         </template>
@@ -155,8 +146,7 @@ export default create({
       };
     });
 
-    const isRange = (val: unknown): val is number[] =>
-      !!props.range && Array.isArray(val);
+    const isRange = (val: unknown): val is number[] => !!props.range && Array.isArray(val);
 
     const calcMainAxis = () => {
       const { modelValue, min } = props;
@@ -273,12 +263,13 @@ export default create({
       const diff = (delta / total) * scope.value;
 
       if (isRange(startValue)) {
-        (currentValue as number[])[buttonIndex.value] =
-          startValue[buttonIndex.value] + diff;
+        (currentValue as number[])[buttonIndex.value] = startValue[buttonIndex.value] + diff;
       } else {
         currentValue = startValue + diff;
       }
       updateValue(currentValue);
+      event.stopPropagation();
+      event.preventDefault();
     };
 
     const onTouchEnd = () => {
@@ -293,10 +284,7 @@ export default create({
     };
 
     const curValue = (idx?: number) => {
-      const value =
-        typeof idx === 'number'
-          ? (props.modelValue as number[])[idx]
-          : props.modelValue;
+      const value = typeof idx === 'number' ? (props.modelValue as number[])[idx] : props.modelValue;
       return value;
     };
 

+ 10 - 43
src/packages/__VUE/uploader/index.taro.vue

@@ -8,11 +8,7 @@
     </view>
 
     <template v-else>
-      <view
-        class="nut-uploader__preview"
-        v-for="(item, index) in fileList"
-        :key="item.uid"
-      >
+      <view class="nut-uploader__preview" v-for="(item, index) in fileList" :key="item.uid">
         <view class="nut-uploader__preview-img">
           <nut-icon
             v-if="isDeletable"
@@ -21,22 +17,12 @@
             class="close"
             name="circle-close"
           ></nut-icon>
-          <image
-            class="nut-uploader__preview-img__c"
-            v-if="item.url"
-            :src="item.url"
-          />
-          <view class="tips" v-if="item.status != 'success'">{{
-            item.status
-          }}</view>
+          <image class="nut-uploader__preview-img__c" v-if="item.url" :src="item.url" />
+          <view class="tips" v-if="item.status != 'success'">{{ item.status }}</view>
         </view>
       </view>
       <view class="nut-uploader__upload" v-if="maximum - fileList.length">
-        <nut-icon
-          :size="uploadIconSize"
-          color="#808080"
-          :name="uploadIcon"
-        ></nut-icon>
+        <nut-icon :size="uploadIconSize" color="#808080" :name="uploadIcon"></nut-icon>
         <nut-button class="nut-uploader__input" @click="chooseImage" />
       </view>
     </template>
@@ -49,12 +35,7 @@ import { createComponent } from '../../utils/create';
 import { Uploader, UploadOptions } from './uploader';
 const { componentName, create } = createComponent('uploader');
 import Taro from '@tarojs/taro';
-export type FileItemStatus =
-  | 'ready'
-  | 'uploading'
-  | 'success'
-  | 'error'
-  | 'removed';
+export type FileItemStatus = 'ready' | 'uploading' | 'success' | 'error' | 'removed';
 export class FileItem {
   status: FileItemStatus = 'ready';
   uid: string = new Date().getTime().toString();
@@ -102,16 +83,7 @@ export default create({
     },
     onChange: { type: Function }
   },
-  emits: [
-    'start',
-    'progress',
-    'oversize',
-    'success',
-    'failure',
-    'change',
-    'delete',
-    'update:fileList'
-  ],
+  emits: ['start', 'progress', 'oversize', 'success', 'failure', 'change', 'delete', 'update:fileList'],
   setup(props, { emit }) {
     const fileList = reactive(props.fileList) as Array<FileItem>;
     const classes = computed(() => {
@@ -154,10 +126,7 @@ export default create({
         emit('progress', { e, option });
       };
 
-      uploadOption.onSuccess = (
-        data: Taro.uploadFile.SuccessCallbackResult,
-        option: UploadOptions
-      ) => {
+      uploadOption.onSuccess = (data: Taro.uploadFile.SuccessCallbackResult, option: UploadOptions) => {
         fileItem.status = 'success';
         emit('success', {
           data,
@@ -165,17 +134,15 @@ export default create({
         });
         emit('update:fileList', fileList);
       };
-      uploadOption.onFailure = (
-        data: Taro.uploadFile.SuccessCallbackResult,
-        option: UploadOptions
-      ) => {
+      uploadOption.onFailure = (data: Taro.uploadFile.SuccessCallbackResult, option: UploadOptions) => {
         fileItem.status = 'error';
         emit('failure', {
           data,
           option
         });
       };
-      new Uploader(uploadOption).uploadTaro(fileItem.path!, Taro);
+
+      new Uploader(uploadOption).uploadTaro(fileItem.path!, Taro.uploadFile);
     };
 
     const readFile = (files: Taro.chooseImage.ImageFile[]) => {

+ 8 - 14
src/packages/__VUE/uploader/uploader.ts

@@ -50,9 +50,9 @@ export class Uploader {
       console.warn('浏览器不支持 XMLHttpRequest');
     }
   }
-  uploadTaro(filePath: string, Taro: any) {
+  uploadTaro(filePath: string, uploadFile: Function) {
     const options = this.options;
-    const uploadTask = Taro.uploadFile({
+    const uploadTask = uploadFile({
       url: options.url,
       filePath,
       header: {
@@ -73,18 +73,12 @@ export class Uploader {
       }
     });
     options.onStart?.(options);
-    uploadTask.progress(
-      (res: {
-        progress: any;
-        totalBytesSent: any;
-        totalBytesExpectedToSend: any;
-      }) => {
-        options.onProgress?.(res, options);
-        // console.log('上传进度', res.progress);
-        // console.log('已经上传的数据长度', res.totalBytesSent);
-        // console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend);
-      }
-    );
+    uploadTask.progress((res: { progress: any; totalBytesSent: any; totalBytesExpectedToSend: any }) => {
+      options.onProgress?.(res, options);
+      // console.log('上传进度', res.progress);
+      // console.log('已经上传的数据长度', res.totalBytesSent);
+      // console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend);
+    });
 
     // uploadTask.abort(); // 取消上传任务
   }

+ 41 - 11
src/packages/utils/useTaroRect/index.ts

@@ -9,18 +9,48 @@
  */
 
 import { Ref, unref } from 'vue';
-
-export const useTaroRect = (
-  elementRef: (Element | Window) | Ref<Element | Window | undefined>,
-  Taro: any
-): any => {
-  const element = unref(elementRef);
+function isWindow(val: unknown): val is Window {
+  return val === window;
+}
+export const useTaroRect = (elementRef: (Element | Window) | Ref<Element | Window | undefined>, Taro: any): any => {
+  let element = unref(elementRef);
 
   return new Promise((resolve) => {
-    const query = Taro.createSelectorQuery();
-    query.select(`#${(element as any).id}`).boundingClientRect();
-    query.exec(function (res: any) {
-      resolve(res[0]);
-    });
+    if (Taro.getEnv() === 'WEB') {
+      if (element && element.$el) {
+        element = element.$el;
+      }
+      if (isWindow(element)) {
+        const width = element.innerWidth;
+        const height = element.innerHeight;
+
+        resolve({
+          top: 0,
+          left: 0,
+          right: width,
+          bottom: height,
+          width,
+          height
+        });
+      }
+      if (element && element.getBoundingClientRect) {
+        resolve(element.getBoundingClientRect());
+      }
+
+      resolve({
+        top: 0,
+        left: 0,
+        right: 0,
+        bottom: 0,
+        width: 0,
+        height: 0
+      });
+    } else {
+      const query = Taro.createSelectorQuery();
+      query.select(`#${(element as any).id}`).boundingClientRect();
+      query.exec(function (res: any) {
+        resolve(res[0]);
+      });
+    }
   });
 };