@xtdev/xt-miniprogram-ui 1.2.42 → 1.2.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * @Author: Mr.Hu
3
3
  * @Date: 2023-12-29 09:48:47
4
- * @Description: 日期组件-js逻辑
4
+ * @Description: 日期组件-支持上拉下拉循环选择
5
5
  * @LastEditors: Mr.Hu
6
6
  */
7
7
  let LASTMONTH = null; // 用于储存上一次选中的月份
@@ -12,7 +12,9 @@ const getDaysInMonth = (year, month) => {
12
12
  };
13
13
  // 深拷贝
14
14
  const deepClone = (val) => {
15
- if (!val) {return null;}
15
+ if (!val) {
16
+ return null;
17
+ }
16
18
  const isObject = (obj) =>
17
19
  Object.prototype.toString.call(obj) === "[object object]";
18
20
  let newResult = Array.isArray(val) ? [] : {};
@@ -107,18 +109,21 @@ Component({
107
109
  checkedType: "start", // 当前选择的日期类型
108
110
  clickedEnd: false, // 点击结束时间
109
111
  filtType: "dateRange", // 选择器模式
112
+ btnDisabled: false, // 按钮禁用
113
+ newDaysArr: [], // 新的天数数组列表,储存拖动之后的天数数组值,用于拖动结束后更新
114
+ newDateArr: [], // 新的选中值,储存拖动之后当前选中的值,用于拖动结束后更新
110
115
  typeEnums: {
111
116
  date: "按日筛选",
112
117
  dateRange: "按月筛选",
113
118
  },
114
- indicatorSyle: "font-size: 40rpx;font-weight: 800;height: 60px",
119
+ indicatorSyle: "font-size: 40rpx;font-weight: 800;height: 60px",// 自定义样式
115
120
  },
116
121
  lifetimes: {
117
122
  created() {},
118
123
  async attached() {
119
124
  await this.initPickerArr();
120
125
  this.setDefaultDate();
121
- await this.handelDays("", true);
126
+ this.handelDays("", true);
122
127
  },
123
128
  },
124
129
  methods: {
@@ -239,9 +244,13 @@ Component({
239
244
  },
240
245
  // 处理传入日期格式
241
246
  transformToArr(dateStr) {
242
- if (!dateStr) {return null;}
247
+ if (!dateStr) {
248
+ return null;
249
+ }
243
250
  const dateArr = dateStr.split("-");
244
- if (!dateArr.length) {return null;}
251
+ if (!dateArr.length) {
252
+ return null;
253
+ }
245
254
  return dateArr;
246
255
  },
247
256
  // 设置默认年月日
@@ -303,143 +312,169 @@ Component({
303
312
  },
304
313
  // 处理当前月的天数
305
314
  handelDays(value, isInitDate = false) {
306
- return new Promise((resolve) => {
315
+ let {
316
+ data: { days, dateArr, years, months, minDate, maxDate, dateValue },
317
+ } = this;
318
+ // 如果没有默认值
319
+ if (!value) {
320
+ const { minYear } = this.getMinAndMaxDate();
307
321
  let {
308
- data: { days, dateArr, years, months, minDate, maxDate, dateValue },
322
+ data: { currentDate },
309
323
  } = this;
310
- // 如果没有默认值
311
- if (!value) {
312
- const { minYear } = this.getMinAndMaxDate();
313
- let {
314
- data: { currentDate },
315
- } = this;
316
- currentDate = currentDate || getDefaultDate();
317
- value = this.transformToArr(currentDate); // 当前日期数组
318
- value = [value[0] - minYear, value[1] - 1, value[2] - 1];
324
+ currentDate = currentDate || getDefaultDate();
325
+ value = this.transformToArr(currentDate); // 当前日期数组
326
+ value = [value[0] - minYear, value[1] - 1, value[2] - 1];
327
+ }
328
+ const selYear = years[value?.[0]],
329
+ selMonth = months[value?.[1]],
330
+ selDay = days[value?.[2]];
331
+ let {
332
+ minYear,
333
+ minMonth,
334
+ maxMonth,
335
+ minDay,
336
+ maxDay,
337
+ selYearColum,
338
+ selMonthColum,
339
+ selDayColum,
340
+ } = this.getMinAndMaxDate(`${selYear}-${selMonth}-${selDay}`, value);
341
+ // 获取当前日期数组,当前选中日期值
342
+ let newDaysArr = days,
343
+ newDateArr = value;
344
+ /****** 处理月份数组下拉列表 start******/
345
+ // 1.后面插入:如果当前选中的是月份,并且是接近最大月,并且当前月份后面没有重复月份,处理月份下拉数组
346
+ const isMonthLastColum =
347
+ selMonth >= maxMonth - 3 && (selMonthColum || selYearColum);
348
+ if (isMonthLastColum || (selMonth >= maxMonth - 3 && isInitDate)) {
349
+ for (let i = minMonth; i <= maxMonth; i++) {
350
+ months.push(i);
319
351
  }
320
- const selYear = years[value?.[0]],
321
- selMonth = months[value?.[1]],
322
- selDay = days[value?.[2]];
323
- let {
324
- minYear,
325
- minMonth,
326
- maxMonth,
327
- minDay,
328
- maxDay,
329
- selYearColum,
330
- selMonthColum,
331
- selDayColum,
332
- } = this.getMinAndMaxDate(`${selYear}-${selMonth}-${selDay}`, value);
333
- // 获取当前日期数组,当前选中日期值
334
- let newDaysArr = days,
335
- newDateArr = value;
336
- /** 处理月数组下拉列表 **/
337
- // 1.后面插入:如果当前选中的是月份,并且是接近最大月,并且当前月份后面没有重复月份,处理月份下拉数组
338
- const isMonthLastColum =
339
- selMonth >= maxMonth - 3 && (selMonthColum || selYearColum);
340
- if (isMonthLastColum || (selMonth >= maxMonth - 3 && isInitDate)) {
341
- for (let i = minMonth; i <= maxMonth; i++) {
342
- months.push(i);
343
- }
344
- this.setData({
345
- months,
346
- });
352
+ this.setData({
353
+ months,
354
+ });
355
+ }
356
+ // 2.前面插入:如果当前选中的是月份,并且是接近最小月,并且当前月份前面没有重复月份,处理月份下拉数组
357
+ const isMonthFirstColum =
358
+ selMonth <= maxMonth - 3 && newDateArr[1] < maxMonth && selMonthColum; // 当前选中的第一月
359
+ if (isMonthFirstColum || (selMonth <= maxMonth - 3 && isInitDate)) {
360
+ for (let i = maxMonth; i >= minMonth; i--) {
361
+ months.unshift(i);
347
362
  }
348
- // 2.前面插入:如果当前选中的是月份,并且是接近最小月,并且当前月份前面没有重复月份,处理月份下拉数组
349
- const isMonthFirstColum =
350
- selMonth <= maxMonth - 3 && newDateArr[1] < maxMonth && selMonthColum; // 当前选中的第一月
351
- if (isMonthFirstColum || (selMonth <= maxMonth - 3 && isInitDate)) {
352
- for (let i = maxMonth; i >= minMonth; i--) {
353
- months.unshift(i);
363
+ newDateArr = [newDateArr[0], newDateArr[1] + maxMonth, newDateArr[2]];
364
+ this.setData({
365
+ months,
366
+ });
367
+ }
368
+ /****** 处理月份数组下拉列表 end******/
369
+
370
+ /****** 处理天数下拉列表 start******/
371
+ const firstIndex = findSecondIndexOf(newDaysArr, (el) => el == 1);
372
+ // 1.切换月份,更新天数组列表
373
+ if (selMonthColum || selYearColum) {
374
+ const newArray = [];
375
+ for (let j = 1; j <= 2; j++) {
376
+ for (let i = minDay; i <= maxDay; i++) {
377
+ newArray.push(i);
354
378
  }
355
- newDateArr = [newDateArr[0], newDateArr[1] + maxMonth, newDateArr[2]];
356
- this.setData({
357
- months,
358
- });
359
379
  }
360
- /** 处理天数下拉列表 **/
361
- const firstIndex = findSecondIndexOf(newDaysArr, (el) => el == 1);
362
- // 2.切换月份,更新天数组列表
363
- if (selMonthColum || selYear) {
364
- const newArray = [];
365
- for (let j = 1; j <= 2; j++) {
366
- for (let i = minDay; i <= maxDay; i++) {
367
- newArray.push(i);
368
- }
369
- }
370
- newDaysArr = newArray;
371
- const beforeMonth = LASTMONTH;
372
- const prevSelDateParams = this.getMinAndMaxDate(`${selYear}-${beforeMonth}-${selDay}`);
373
- // 如果选中的是当月第一天,处理当前选中的下标逻辑
374
- if (selDay == 1) {
375
- // 获取切换之前的月数
376
- const valueDay = maxDay - prevSelDateParams.maxDay;
377
- newDateArr = [newDateArr[0], newDateArr[1], newDateArr[2] + valueDay];
378
- }
379
- // 如果选中的是当月最后一天,处理当前选中的下标逻辑
380
- if (selDay == prevSelDateParams.maxDay) {
381
- // 获取当前月天数
382
- const curSelDateParams = this.getMinAndMaxDate(`${selYear}-${selMonth}-${selDay}`);
383
- newDateArr = [newDateArr[0], newDateArr[1], curSelDateParams.maxDay - 1];
384
- }
380
+ newDaysArr = newArray; // 重置当前月的天数组列表
381
+ const beforeMonth = LASTMONTH; // 获取上次选择月数
382
+ // 获取切换之前月选中信息
383
+ const prevSelDateParams = this.getMinAndMaxDate(
384
+ `${selYear}-${beforeMonth}-${selDay}`
385
+ );
386
+ // 如果选中的是当月第一天,处理当前选中的下标逻辑
387
+ if (selDay == 1) {
388
+ const valueDay = maxDay - prevSelDateParams.maxDay;
389
+ newDateArr = [newDateArr[0], newDateArr[1], newDateArr[2] + valueDay];
385
390
  }
386
- // 天数列表上拉循环选择--后面插入
387
- // 1.如果当前选中的是天数,并且是接近最大天数,并且当前天数后面没有重复天数,处理天数下拉数组
388
- const isDayLastColum = selDayColum && selDay >= maxDay - 3;
389
- // 获取上一个月的天数
390
- if (isDayLastColum || (isInitDate && selDay >= maxDay - 3)) {
391
- // 如果当前选中的不是天数组最后三条数据,重新组装
392
- if (newDaysArr.length > 58 && value[2] <= newDaysArr.length - 3) {
393
- newDaysArr = newDaysArr.slice(firstIndex + 1, newDaysArr.length);
394
- }
395
- for (let i = minDay; i <= maxDay; i++) {
396
- newDaysArr.push(i);
397
- }
398
- this.setData({
399
- days: newDaysArr,
400
- });
391
+ // 如果选中的是当月最后一天,处理当前选中的下标逻辑
392
+ if (selDay == prevSelDateParams.maxDay) {
393
+ // 获取当前月天数
394
+ const curSelDateParams = this.getMinAndMaxDate(
395
+ `${selYear}-${selMonth}-${selDay}`
396
+ );
397
+ newDateArr = [
398
+ newDateArr[0],
399
+ newDateArr[1],
400
+ curSelDateParams.maxDay - 1,
401
+ ];
401
402
  }
402
- // 天数列表上拉循环选择--前面插入
403
- // 1.当前选中天数列表,选中的接近最小天数,并且设置的天数小于最大天数
404
- const isDayFirstColum =
405
- selDay <= minDay + 3 && newDateArr[2] < maxDay && selDayColum; // 当前选中的第一日
406
- // 2. 当前初始日期前面设置添加循环选择
407
- if (isDayFirstColum || (isInitDate && selDay <= minDay + 3)) {
408
- for (let i = maxDay; i >= minDay; i--) {
409
- newDaysArr.unshift(i);
410
- }
411
- this.setData({
412
- days: newDaysArr,
413
- });
414
- let valueDay = Number(newDateArr[2] + maxDay);
415
- newDateArr = [newDateArr[0], newDateArr[1], valueDay];
403
+ }
404
+ // 天数列表上拉循环选择--后面插入
405
+ // 前选中天数列表,选中的接近最大天数,并且当前天数后面没有重复天数,处理天数下拉数组
406
+ const isDayLastColum = selDayColum && selDay >= maxDay - 3;
407
+ // 获取上一个月的天数
408
+ if (isDayLastColum || (isInitDate && selDay >= maxDay - 3)) {
409
+ // 如果当前选中的不是天数组最后三条数据,重新组装
410
+ if (
411
+ newDaysArr.length > 2 * maxDay &&
412
+ value[2] <= newDaysArr.length - 3
413
+ ) {
414
+ newDaysArr = newDaysArr.slice(firstIndex + 1, newDaysArr.length);
416
415
  }
417
- LASTMONTH = selMonth;// 储存当前选中的月份,为上次选中的月份
418
- // 天数选择下拉循环选择
419
- // 解决回弹动画延时问题
420
- if ((isMonthFirstColum || isDayFirstColum) && !this.data.isRset) {
421
- setTimeout(() => {
422
- this.setData({
423
- days: newDaysArr,
424
- dateArr: newDateArr,
425
- });
426
- resolve();
427
- }, 1500);
428
- } else {
416
+ for (let i = minDay; i <= maxDay; i++) {
417
+ newDaysArr.push(i);
418
+ }
419
+ }
420
+ // 天数列表上拉循环选择--前面插入
421
+ // 当前选中天数列表,选中的接近最小天数,并且设置的天数小于最大天数
422
+ const isDayFirstColum =
423
+ selDay <= minDay + 3 && newDateArr[2] < maxDay && selDayColum; // 当前选中的第一日
424
+ if (isDayFirstColum || (isInitDate && selDay <= minDay + 3)) {
425
+ for (let i = maxDay; i >= minDay; i--) {
426
+ newDaysArr.unshift(i);
427
+ }
428
+ let valueDay = newDateArr[2] + maxDay;
429
+ newDateArr = [newDateArr[0], newDateArr[1], valueDay];
430
+ this.setData({
431
+ days: newDaysArr,
432
+ dateArr: newDateArr
433
+ }, () => {
429
434
  this.setData({
430
- days: newDaysArr,
431
- dateArr: newDateArr,
432
- isRset: false,
435
+ dateArr: newDateArr
433
436
  });
434
- resolve();
435
- }
437
+ });
438
+ }
439
+ /****** 处理天数循环选择列表 end******/
440
+
441
+ LASTMONTH = selMonth; // 储存当前选中的月份,为上次选中的月份
442
+ // 处理快速拉动引发的bug
443
+ if (newDateArr[2] > newDaysArr.length) {
444
+ newDateArr = [newDateArr[0], newDateArr[1], newDaysArr.length - 1];
445
+ }
446
+ // 天数选择下拉循环选择
447
+ this.setData({
448
+ newDaysArr,
449
+ newDateArr,
436
450
  });
437
451
  },
452
+ // 监听滚动开始,禁用确认按钮
453
+ bindPickstart(e) {
454
+ this.setData({
455
+ btnDisabled: true
456
+ });
457
+ },
458
+ // 监听滚动结束:滚动结束,更新选中时间
459
+ bindPickend(e) {
460
+ const {
461
+ data: { newDaysArr, newDateArr },
462
+ } = this;
463
+ this.setData({
464
+ days: newDaysArr,
465
+ dateArr: newDateArr,
466
+ btnDisabled: false
467
+ });
468
+ this.updateChangeValue();
469
+ },
438
470
  // 滑动下拉列表
439
471
  async bindChange(e) {
440
472
  const value = e?.detail?.value;
441
473
  // 处理每月可选天数
442
- await this.handelDays(value);
474
+ this.handelDays(value);
475
+ },
476
+ // 更新选中的值
477
+ updateChangeValue() {
443
478
  let {
444
479
  data: {
445
480
  years,
@@ -559,7 +594,6 @@ Component({
559
594
  },
560
595
  // 重置时间
561
596
  async onReset() {
562
- this.setData({ isRset: true });
563
597
  this.bindChange();
564
598
  },
565
599
  // 关闭选择器
@@ -31,7 +31,9 @@
31
31
  indicator-style="{{indicatorSyle}}"
32
32
  immediate-change="{{true}}"
33
33
  mask-class="picker-mask"
34
- bindchange="bindChange">
34
+ bindchange="bindChange"
35
+ bindpickstart="bindPickstart"
36
+ bindpickend="bindPickend">
35
37
  <picker-view-column>
36
38
  <view wx:for="{{years}}" wx:key="index" class="picker-item {{dateArr[0] === index ? 'picker-select' : ''}}">
37
39
  {{item}}年
@@ -51,7 +53,7 @@
51
53
  <!-- 按钮组 -->
52
54
  <view class="btns-group">
53
55
  <xt-button catchtap="onReset" class="btn-reset">{{cancelButtonText}}</xt-button>
54
- <xt-button catchtap="onConfirm" type="main" class="btn-confirm">{{confirmButtonText}}</xt-button>
56
+ <xt-button catchtap="onConfirm" disabled="{{btnDisabled}}" type="main" class="btn-confirm">{{confirmButtonText}}</xt-button>
55
57
  </view>
56
58
  </view>
57
59
  </view>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xtdev/xt-miniprogram-ui",
3
- "version": "1.2.42",
3
+ "version": "1.2.43",
4
4
  "description": "",
5
5
  "miniprogram": "libs",
6
6
  "publishConfig": {