Browse Source

fix: progress optimization add new props

Drjnigfubo 3 years ago
parent
commit
1d21048b63

+ 1 - 1
src/packages/__VUE/progress/demo.vue

@@ -53,7 +53,7 @@
         />
       </nut-cell>
       <nut-cell>
-        <nut-progress percentage="50" :stroke-width="strokeWidth" status="icon" />
+        <nut-progress percentage="50" status="icon" />
       </nut-cell>
       <nut-cell>
         <nut-progress

+ 1 - 0
src/packages/__VUE/progress/doc.md

@@ -127,6 +127,7 @@ app.use(Icon);
 | 字段 | 说明 | 类型 | 默认值
 |----- | ----- | ----- | -----
 | percentage | 百分比 | Number | 0
+| is-show-percentage="false" | 是否需要展示百分号 | Boolean | true
 | stroke-color | 进度条背景色 | String | #f30
 | stroke-width | 进度条宽度 | String | ''
 | size | 进度条及文字尺寸,可选值small/base/large | String | -

+ 49 - 44
src/packages/__VUE/progress/index.taro.vue

@@ -2,33 +2,26 @@
   <div class="nut-progress">
     <div
       class="nut-progress-outer"
+      :id="'nut-progress-outer-taro-' + randRef"
       ref="progressOuter"
-      :class="[
-        showText && !textInside ? 'nut-progress-outer-part' : '',
-        size ? 'nut-progress-' + size : ''
-      ]"
+      :class="[showText && !textInside ? 'nut-progress-outer-part' : '', size ? 'nut-progress-' + size : '']"
       :style="{ height: height }"
     >
-      <div
-        :class="['nut-progress-inner', status == 'active' ? 'nut-active' : '']"
-        :style="bgStyle"
-      >
+      <div :class="['nut-progress-inner', status == 'active' ? 'nut-active' : '']" :style="bgStyle">
         <div
           class="nut-progress-text nut-progress-insidetext"
+          ref="insideText"
+          :id="'nut-progress-insidetext-taro-' + randRef"
           :style="{ lineHeight: height, left: left }"
           v-if="showText && textInside"
         >
-          <span :style="textStyle">{{ percentage }}%</span>
+          <span :style="textStyle">{{ percentage }}{{ isShowPercentage ? '%' : '' }}</span>
         </div>
       </div>
     </div>
-    <div
-      class="nut-progress-text"
-      :style="{ lineHeight: height }"
-      v-if="showText && !textInside"
-    >
+    <div class="nut-progress-text" :style="{ lineHeight: height }" v-if="showText && !textInside">
       <template v-if="status == 'text' || status == 'active'">
-        <span :style="textStyle">{{ percentage }}%</span>
+        <span :style="textStyle">{{ percentage }}{{ isShowPercentage ? '%' : '' }} </span>
       </template>
       <template v-else-if="status == 'icon'">
         <nut-icon size="16px" :name="iconName" :color="iconColor"></nut-icon>
@@ -38,18 +31,10 @@
 </template>
 
 <script lang="ts">
-import {
-  computed,
-  onMounted,
-  provide,
-  reactive,
-  nextTick,
-  ref,
-  getCurrentInstance,
-  watch
-} from 'vue';
+import { computed, onMounted, provide, reactive, nextTick, ref, watch } from 'vue';
 import { createComponent } from '../../utils/create';
-import Taro, { eventCenter } from '@tarojs/taro';
+import Taro, { eventCenter, getCurrentInstance } from '@tarojs/taro';
+import { log } from 'lzutf8';
 const { create } = createComponent('progress');
 export default create({
   props: {
@@ -93,12 +78,19 @@ export default create({
     iconColor: {
       type: String,
       default: '#439422'
+    },
+    isShowPercentage: {
+      type: Boolean,
+      default: true
     }
   },
   setup(props, { emit }) {
     const height = ref(props.strokeWidth + 'px');
     const progressOuter = ref<any>();
     const left = ref();
+    const insideText = ref();
+    const refRandomId = Math.random().toString(36).slice(-8);
+    const randRef = ref(refRandomId);
     const bgStyle = computed(() => {
       return {
         width: props.percentage + '%',
@@ -110,38 +102,51 @@ export default create({
         color: props.textColor || ''
       };
     });
-    const slideLeft = async (values: String | Number) => {
+    const slideLeft = async (values: string | number) => {
       if (Taro.getEnv() === 'WEB') {
-        setTimeout(() => {
-          left.value =
-            progressOuter.value.offsetWidth * Number(values) * 0.01 - 4 + 'px';
-        }, 200);
+        if (!props.textInside) return;
+        let offsetWidth = progressOuter.value.offsetWidth;
+        let percentageWidth = progressOuter.value.offsetWidth * Number(values) * 0.01;
+        let insideTextWidth = insideText.value.offsetWidth;
+        left.value = percentageWidth - 5 + 'px';
+        if (offsetWidth == percentageWidth) {
+          left.value = percentageWidth - insideTextWidth + 'px';
+        }
       } else {
-        setTimeout(() => {
-          const query = Taro.createSelectorQuery() as any;
-          query
-            .select('.nut-progress-outer')
-            .boundingClientRect((rec: any) => {
-              left.value = rec.width * Number(values) * 0.01 - 4 + 'px';
-            })
-            .exec();
-        }, 200);
+        if (!props.textInside) return;
+        const query = Taro.createSelectorQuery() as any;
+        query.select('#nut-progress-outer-taro-' + randRef.value).boundingClientRect();
+        query.select('#nut-progress-insidetext-taro-' + randRef.value).boundingClientRect();
+        query.exec((res: any) => {
+          let offsetWidth = res[0].width;
+          let percentageWidth = res[0].width * Number(values) * 0.01;
+          let insideTextWidth = res[1].width;
+          left.value = percentageWidth - 4 + 'px';
+          if (offsetWidth == percentageWidth) {
+            left.value = percentageWidth - insideTextWidth + 'px';
+          }
+        });
       }
     };
     watch(
       () => props.percentage,
       (values) => {
         slideLeft(values);
-      },
-      { immediate: true }
+      }
     );
-    onMounted(() => {});
+    onMounted(() => {
+      eventCenter.once((getCurrentInstance() as any).router.onReady, () => {
+        slideLeft(props.percentage);
+      });
+    });
     return {
       height,
       bgStyle,
       textStyle,
       progressOuter,
-      left
+      left,
+      insideText,
+      randRef
     };
   }
 });

+ 24 - 11
src/packages/__VUE/progress/index.vue

@@ -9,16 +9,17 @@
       <div :class="['nut-progress-inner', status == 'active' ? 'nut-active' : '']" :style="bgStyle">
         <div
           class="nut-progress-text nut-progress-insidetext"
+          ref="insideText"
           :style="{ lineHeight: height, left: left }"
           v-if="showText && textInside"
         >
-          <span :style="textStyle">{{ percentage }}%</span>
+          <span :style="textStyle">{{ percentage }}{{ isShowPercentage ? '%' : '' }} </span>
         </div>
       </div>
     </div>
     <div class="nut-progress-text" :style="{ lineHeight: height }" v-if="showText && !textInside">
       <template v-if="status == 'active' || status == ''">
-        <span :style="textStyle">{{ percentage }}%</span>
+        <span :style="textStyle">{{ percentage }}{{ isShowPercentage ? '%' : '' }}</span>
       </template>
       <template v-else-if="status == 'icon'">
         <nut-icon size="16px" :name="iconName" :color="iconColor"></nut-icon>
@@ -28,6 +29,7 @@
 </template>
 
 <script lang="ts">
+import { log } from 'lzutf8';
 import { computed, onMounted, provide, reactive, nextTick, ref, watch } from 'vue';
 import { createComponent } from '../../utils/create';
 const { create } = createComponent('progress');
@@ -73,11 +75,16 @@ export default create({
     iconColor: {
       type: String,
       default: '#439422'
+    },
+    isShowPercentage: {
+      type: Boolean,
+      default: true
     }
   },
   setup(props, { emit }) {
     const height = ref(props.strokeWidth + 'px');
     const progressOuter = ref();
+    const insideText = ref();
     const left = ref();
     const bgStyle = computed(() => {
       return {
@@ -91,27 +98,33 @@ export default create({
       };
     });
 
+    const slideLeft = (values: string | number) => {
+      if (props.textInside) {
+        let offsetWidth = progressOuter.value.offsetWidth;
+        let percentageWidth = progressOuter.value.offsetWidth * Number(values) * 0.01;
+        let insideTextWidth = insideText.value.offsetWidth;
+        left.value = percentageWidth - 5 + 'px';
+        if (offsetWidth == percentageWidth) {
+          left.value = percentageWidth - insideTextWidth + 'px';
+        }
+      }
+    };
+
     watch(
       () => props.percentage,
       (values) => {
-        // console.log(
-        //   'progressOuter.value.offsetWidth',
-        //   progressOuter.value.offsetWidth
-        // );
-
-        // console.log('values', values);
-
-        left.value = progressOuter.value.offsetWidth * Number(values) * 0.01 - 5 + 'px';
+        slideLeft(values);
       }
     );
     onMounted(() => {
-      left.value = progressOuter.value.offsetWidth * Number(props.percentage) * 0.01 - 5 + 'px';
+      slideLeft(props.percentage);
     });
     return {
       height,
       bgStyle,
       textStyle,
       progressOuter,
+      insideText,
       left
     };
   }

+ 3 - 3
src/sites/doc/components/demo-block/demoBlock.vue

@@ -71,10 +71,10 @@ createApp(App).use(NutUI).mount("#app");`;
     const jumpHref = ref(``);
     const jumpHref1 = ref(``);
     onMounted(() => {
-      console.log('codesandboxPackage', codesandboxPackage);
-      console.log('onlineCode', onlineCode.value.dataset);
+      // console.log('codesandboxPackage', codesandboxPackage);
+      // console.log('onlineCode', onlineCode.value.dataset);
       const sourceValue = decompressText(onlineCode.value.dataset.value);
-      console.log('sourceValue', sourceValue);
+      // console.log('sourceValue', sourceValue);
 
       const parameters = getParameters({
         files: {

+ 12 - 0
src/sites/mobile-taro/vue/project.private.config.json

@@ -35,6 +35,18 @@
           "pathName": "feedback/pages/collapse/index",
           "query": "",
           "scene": null
+        },
+        {
+          "name": "feedback/pages/progress/index",
+          "pathName": "feedback/pages/progress/index",
+          "query": "",
+          "scene": null
+        },
+        {
+          "name": "feedback/pages/swiper/index",
+          "pathName": "feedback/pages/swiper/index",
+          "query": "",
+          "scene": null
         }
       ]
     }