Browse Source

fix: Picker 在Taro适配中的优化以及Issue 问题修改(#1620、#1572) (#1621)

* feat: taro-picker 问题修改

* fix: 解决Taro高度问题

* fix: 组件datePicker添加 swipeDuration 与 three-dimensional 属性

* fix: #1572问题修改

* feat: 更新Picker组件在Taro中获取高度的方式
yangxiaolu1993 3 years ago
parent
commit
8d468783a1

+ 1 - 1
project.config.json

@@ -44,7 +44,7 @@
   },
   "compileType": "miniprogram",
   "libVersion": "2.24.4",
-  "appid": "wx9ac45039b7813c7d",
+  "appid": "wxf2b976b67dab3882",
   "projectname": "nutui",
   "condition": {},
   "editorSetting": {

+ 1 - 0
src/packages/__VUE/datepicker/demo.vue

@@ -40,6 +40,7 @@
       "
       v-model:visible="show"
       :is-show-chinese="true"
+      :threeDimensional="false"
     ></nut-datepicker>
     <!-- 选择月日 -->
     <nut-datepicker

+ 2 - 0
src/packages/__VUE/datepicker/doc.en-US.md

@@ -32,6 +32,7 @@ app.use(OverLay);
       :min-date="minDate"
       :max-date="maxDate"
       :is-show-chinese="true"
+      :three-dimensional="false"
       @confirm="confirm"
   ></nut-datepicker> 
 </template>
@@ -378,6 +379,7 @@ app.use(OverLay);
 | ok-text           | Text of confirm button                                      | String  | confirm   |
 | cancel-text           | Text of cancel button                                          | String  | cancel   |
 | three-dimensional  `v3.1.23`          | Turn on 3D effects               | Boolean  | true   |
+| swipe-duration `v3.2.2`          | Duration of the momentum animation        | Number、String  | 1000   |
 
 ### Events
 

+ 3 - 1
src/packages/__VUE/datepicker/doc.md

@@ -33,6 +33,7 @@ app.use(OverLay);
       :min-date="minDate"
       :max-date="maxDate"
       :is-show-chinese="true"
+      :three-dimensional="false"
       @confirm="confirm"
   ></nut-datepicker> 
 </template>
@@ -387,7 +388,8 @@ DatetimePicker 通过 type 属性来定义需要选择的时间类型。将 type
 | title           | 设置标题                                          | String  | `null`   |
 | ok-text           | 确定按钮文案                                          | String  | 确定   |
 | cancel-text           | 取消按钮文案                                          | String  | 取消   |
-| three-dimensional`小程序不支持` `v3.1.23`          | 是否开启3D效果               | Boolean  | true   |
+| three-dimensional `v3.1.23`          | 是否开启3D效果               | Boolean  | true   |
+| swipe-duration `v3.2.2`          | 惯性滚动时长               | Number、String  | 1000    |
 
 ### Events
     

+ 12 - 1
src/packages/__VUE/datepicker/index.taro.vue

@@ -10,6 +10,8 @@
     :title="title"
     @confirm="confirm"
     :isWrapTeleport="isWrapTeleport"
+    :threeDimensional="threeDimensional"
+    :swipeDuration="swipeDuration"
   >
     <template #top>
       <slot name="top"></slot>
@@ -86,6 +88,16 @@ export default create({
       type: Function as PropType<import('./type').Formatter>,
       default: null
     },
+    // 是否开启3D效果
+    threeDimensional: {
+      type: Boolean,
+      default: true
+    },
+    // 惯性滚动 时长
+    swipeDuration: {
+      type: [Number, String],
+      default: 1000
+    },
     filter: Function as PropType<import('./type').Filter>
   },
   emits: ['click', 'update:visible', 'change', 'confirm', 'update:moduleValue'],
@@ -137,7 +149,6 @@ export default create({
           }
         }
       }
-
       return {
         [`${type}Year`]: year,
         [`${type}Month`]: month,

+ 6 - 0
src/packages/__VUE/datepicker/index.vue

@@ -11,6 +11,7 @@
     @confirm="confirm"
     :isWrapTeleport="isWrapTeleport"
     :threeDimensional="threeDimensional"
+    :swipeDuration="swipeDuration"
   >
     <template #top>
       <slot name="top"></slot>
@@ -93,6 +94,11 @@ export default create({
       type: Boolean,
       default: true
     },
+    // 惯性滚动 时长
+    swipeDuration: {
+      type: [Number, String],
+      default: 1000
+    },
     filter: Function as PropType<import('./type').Filter>
   },
   emits: ['click', 'update:visible', 'change', 'confirm', 'update:moduleValue'],

+ 14 - 43
src/packages/__VUE/picker/ColumnTaro.vue

@@ -18,20 +18,12 @@
           {{ item.text }}
         </view>
         <!-- 平铺 -->
-        <view
-          class="nut-picker-roller-item-tile"
-          ref="listbox"
-          :id="'listbox' + refRandomId"
-          v-if="item && item.text && !threeDimensional"
-        >
+        <view class="nut-picker-roller-item-tile" v-if="item && item.text && !threeDimensional">
           {{ item.text }}
         </view>
       </template>
     </view>
     <view class="nut-picker-roller-mask"></view>
-    <view class="nut-picker-content" ref="listbox" :id="'listbox' + refRandomId" v-if="threeDimensional">
-      <view class="nut-picker-list-panel" ref="list" :id="'list' + refRandomId" :style="touchTileStyle"> </view>
-    </view>
   </view>
 </template>
 <script lang="ts">
@@ -48,6 +40,10 @@ export default create({
     // 当前选中项
     value: [String, Number],
     columnsType: String,
+    lineSpacing: {
+      type: Number,
+      default: 36
+    },
     itemShow: {
       type: Boolean,
       default: false
@@ -89,7 +85,6 @@ export default create({
       currIndex: 1,
       transformY: 0,
       scrollDistance: 0,
-      lineSpacing: 36,
       rotation: 20,
       timer: null
     });
@@ -97,7 +92,6 @@ export default create({
     const roller = ref(null);
     const list = ref(null);
     const listitem = ref(null);
-    const listbox = ref(null);
 
     const moving = ref(false); // 是否处于滚动中
     const touchDeg = ref(0);
@@ -223,13 +217,13 @@ export default create({
         if (updateMove > 0) {
           updateMove = 0;
         }
-        if (updateMove < -(props.column.length - 1) * state.lineSpacing) {
-          updateMove = -(props.column.length - 1) * state.lineSpacing;
+        if (updateMove < -(props.column.length - 1) * props.lineSpacing) {
+          updateMove = -(props.column.length - 1) * props.lineSpacing;
         }
 
         // 设置滚动距离为lineSpacing的倍数值
-        let endMove = Math.round(updateMove / state.lineSpacing) * state.lineSpacing;
-        let deg = `${(Math.abs(Math.round(endMove / state.lineSpacing)) + 1) * state.rotation}deg`;
+        let endMove = Math.round(updateMove / props.lineSpacing) * props.lineSpacing;
+        let deg = `${(Math.abs(Math.round(endMove / props.lineSpacing)) + 1) * state.rotation}deg`;
         setTransform(endMove, type, time, deg);
 
         // let t = time ? time / 2 : 0;
@@ -237,10 +231,10 @@ export default create({
         //   setChooseValue();
         // }, t);
 
-        state.currIndex = Math.abs(Math.round(endMove / state.lineSpacing)) + 1;
+        state.currIndex = Math.abs(Math.round(endMove / props.lineSpacing)) + 1;
       } else {
         let deg = 0;
-        let currentDeg = (-updateMove / state.lineSpacing + 1) * state.rotation;
+        let currentDeg = (-updateMove / props.lineSpacing + 1) * state.rotation;
 
         // picker 滚动的最大角度
         const maxDeg = (props.column.length + 1) * state.rotation;
@@ -250,7 +244,7 @@ export default create({
 
         if (minDeg < deg && deg < maxDeg) {
           setTransform(updateMove, null, undefined, deg + 'deg');
-          state.currIndex = Math.abs(Math.round(updateMove / state.lineSpacing)) + 1;
+          state.currIndex = Math.abs(Math.round(updateMove / props.lineSpacing)) + 1;
         }
       }
     };
@@ -264,7 +258,7 @@ export default create({
       let index = column.findIndex((columnItem) => columnItem.value == props.value);
 
       state.currIndex = index === -1 ? 1 : (index as number) + 1;
-      let move = index === -1 ? 0 : (index as number) * state.lineSpacing;
+      let move = index === -1 ? 0 : (index as number) * props.lineSpacing;
       type && setChooseValue();
       setMove(-move);
     };
@@ -287,12 +281,6 @@ export default create({
       setChooseValue();
     };
 
-    const getReference = async () => {
-      const refe = await useTaroRect(listbox, Taro);
-      state.lineSpacing = refe.height ? refe.height : 36;
-      modifyStatus(true);
-    };
-
     watch(
       () => props.column,
       (val) => {
@@ -307,20 +295,6 @@ export default create({
     );
 
     watch(
-      () => props.itemShow,
-      (val) => {
-        if (val) {
-          setTimeout(() => {
-            getReference();
-          }, 200);
-        }
-      },
-      {
-        deep: true
-      }
-    );
-
-    watch(
       () => props.value,
       (val) => {
         state.transformY = 0;
@@ -332,9 +306,7 @@ export default create({
     );
 
     onMounted(() => {
-      setTimeout(() => {
-        getReference();
-      }, 200);
+      modifyStatus(false);
     });
 
     const refRandomId = Math.random().toString(36).slice(-8);
@@ -349,7 +321,6 @@ export default create({
       roller,
       list,
       listitem,
-      listbox,
       onTouchStart,
       onTouchMove,
       onTouchEnd,

+ 3 - 0
src/packages/__VUE/picker/demo.vue

@@ -88,6 +88,7 @@
     ></nut-cell>
     <nut-picker
       v-model:visible="showCascader"
+      v-model="selectedCascader"
       :columns="cascaderColumns"
       :title="translate('chooseCity')"
       @confirm="(options) => confirm('cascader', options)"
@@ -145,6 +146,7 @@ export default createDemo({
   setup() {
     const selectedValue = ref(['ZheJiang']);
     const selectedTime = ref(['Wednesday', 'Afternoon']);
+    const selectedCascader = ref(['FuJian', 'FuZhou', 'TaiJiang']);
     const asyncValue = ref<string[]>([]);
     const columsNum = ref([]);
     const columns = computed(() => [
@@ -392,6 +394,7 @@ export default createDemo({
       alwaysFun,
       translate,
       selectedTime,
+      selectedCascader,
       columsNum,
       showTile,
       showJK,

+ 3 - 1
src/packages/__VUE/picker/doc.en-US.md

@@ -224,6 +224,7 @@ Use the children field of the Columns attribute to cascade options
   <nut-cell title="Choose City" :desc="desc" @click="()=>{show=true}"></nut-cell>
   <nut-picker
     v-model:visible="show"
+    v-model="selectedCascader"
     :columns="cascaderColumns"
     title="Choose City"
     @confirm="confirm"
@@ -236,6 +237,7 @@ Use the children field of the Columns attribute to cascade options
     setup(props) {
       const show = ref(false);
       const desc = ref('');
+      const selectedCascader = ref(['FuJian', 'FuZhou','TaiJiang']);
       const cascaderColumns = ref([
         {
           text: 'ZheJiang',
@@ -290,7 +292,7 @@ Use the children field of the Columns attribute to cascade options
         console.log(selectedValue);
       };
 
-      return {show,desc,cascaderColumns,change, confirm};
+      return {show,desc,selectedCascader,cascaderColumns,change, confirm};
     }
   };
 </script>

+ 3 - 1
src/packages/__VUE/picker/doc.md

@@ -231,6 +231,7 @@ columns 属性可以通过二维数组的形式配置多列选择。
   <nut-cell title="请选择城市" :desc="desc" @click="()=>{show=true}"></nut-cell>
   <nut-picker
     v-model:visible="show"
+    v-model="selectedCascader"
     :columns="cascaderColumns"
     title="城市选择"
     @confirm="confirm"
@@ -243,6 +244,7 @@ columns 属性可以通过二维数组的形式配置多列选择。
     setup(props) {
       const show = ref(false);
       const desc = ref('');
+      const selectedCascader = ref(['FuJian', 'FuZhou','TaiJiang']);
       const cascaderColumns = ref([
         {
           text: '浙江',
@@ -297,7 +299,7 @@ columns 属性可以通过二维数组的形式配置多列选择。
         console.log(selectedValue);
       };
 
-      return {show,desc,cascaderColumns,change, confirm};
+      return {show,desc,selectedCascader,cascaderColumns,change, confirm};
     }
   };
 </script>

+ 31 - 6
src/packages/__VUE/picker/index.taro.vue

@@ -20,7 +20,7 @@
       </view>
       <slot name="top"></slot>
       <view class="nut-picker__column">
-        <view class="nut-picker__hairline"></view>
+        <view class="nut-picker__hairline" ref="pickerline" :id="'pickerline' + refRandomId"></view>
         <view class="nut-picker__columnitem" v-for="(column, columnIndex) in columnsList" :key="columnIndex">
           <nut-picker-column
             :ref="swipeRef"
@@ -31,6 +31,7 @@
             :value="defaultValues[columnIndex]"
             :threeDimensional="threeDimensional"
             :swipeDuration="swipeDuration"
+            :lineSpacing="lineSpacing"
             @change="
               (option) => {
                 changeHandler(columnIndex, option);
@@ -48,6 +49,8 @@ import { ref, onMounted, onBeforeUnmount, reactive, watch, computed, toRaw, toRe
 import { createComponent } from '@/packages/utils/create';
 import { popupProps } from '../popup/index.taro.vue';
 import column from './ColumnTaro.vue';
+import { useTaroRect } from '@/packages/utils/useTaroRect';
+import Taro from '@tarojs/taro';
 const { componentName, create, translate } = createComponent('picker');
 export default create({
   components: {
@@ -96,9 +99,12 @@ export default create({
   setup(props, { emit }) {
     const state = reactive({
       show: false,
-      formattedColumns: props.columns as import('./types').PickerOption[]
+      formattedColumns: props.columns as import('./types').PickerOption[],
+      lineSpacing: 36
     });
 
+    const pickerline = ref(null);
+
     // 选中项
     let defaultValues = ref<(number | string)[]>(props.modelValue);
 
@@ -235,8 +241,20 @@ export default create({
       emit('update:visible', false);
     };
 
+    const refRandomId = Math.random().toString(36).slice(-8);
+
+    const getReference = async () => {
+      const refe = await useTaroRect(pickerline, Taro);
+      state.lineSpacing = refe.height ? refe.height : 36;
+    };
+
     onMounted(() => {
-      if (props.visible) state.show = props.visible;
+      if (props.visible) {
+        setTimeout(() => {
+          getReference();
+        }, 200);
+        state.show = props.visible;
+      }
     });
 
     onBeforeUnmount(() => {
@@ -269,8 +287,13 @@ export default create({
       () => props.visible,
       (val) => {
         state.show = val;
-        console.log(defaultValues.value);
-        if (val) pickerColumn.value = [];
+        if (val) {
+          setTimeout(() => {
+            getReference();
+          }, 200);
+
+          pickerColumn.value = [];
+        }
       }
     );
 
@@ -293,7 +316,9 @@ export default create({
       defaultValues,
       translate,
       pickerColumn,
-      swipeRef
+      swipeRef,
+      refRandomId,
+      pickerline
     };
   }
 });

+ 1 - 0
src/sites/mobile-taro/vue/src/dentry/pages/datepicker/index.vue

@@ -25,6 +25,7 @@
         }
       "
       v-model:visible="show"
+      :threeDimensional="false"
       :is-show-chinese="true"
     ></nut-datepicker>
     <!-- 选择月日 -->

+ 8 - 2
src/sites/mobile-taro/vue/src/dentry/pages/picker/index.vue

@@ -68,6 +68,7 @@
       "
     ></nut-cell>
     <nut-picker
+      v-model="selectedTime"
       v-model:visible="showMultiple"
       :columns="multipleColumns"
       title="城市选择"
@@ -86,6 +87,7 @@
       "
     ></nut-cell>
     <nut-picker
+      v-model="selectedCascader"
       v-model:visible="showCascader"
       :columns="cascaderColumns"
       title="城市选择"
@@ -129,7 +131,7 @@
       <nut-button block type="primary" @click="alwaysFun">永远有效</nut-button></nut-picker
     >
 
-    <h2>异步获取</h2>
+    <!-- <h2>异步获取</h2>
     <nut-cell
       title="异步获取"
       :desc="effect"
@@ -145,7 +147,7 @@
       title="异步获取"
       @confirm="(options) => confirm('effect', options)"
       @change="portChange"
-    ></nut-picker>
+    ></nut-picker> -->
   </div>
 </template>
 <script lang="ts">
@@ -155,6 +157,8 @@ export default {
   props: {},
   setup() {
     const selectedValue = ref(['ZheJiang']);
+    const selectedTime = ref(['Wednesday', 'Afternoon']);
+    const selectedCascader = ref(['FuJian', 'FuZhou', 'TaiJiang']);
     const asyncValue = ref<string[]>([]);
     const columsNum = ref([]);
     const columns = ref([
@@ -361,6 +365,8 @@ export default {
     };
     return {
       selectedValue,
+      selectedTime,
+      selectedCascader,
       asyncValue,
       columns,
       show,