|
@@ -8,7 +8,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <picker-view v-if="visible" class="picker-view" :indicator-style="indicatorStyle" :value="pickerValue" @change="handleChange">
|
|
|
|
|
|
|
+ <picker-view v-if="visible" class="picker-view" :indicator-style="indicatorStyle" :value="pickerValue" @change="handleChange" :immediate-change="true">
|
|
|
<picker-view-column>
|
|
<picker-view-column>
|
|
|
<view class="picker-item" v-for="(item, index) in days" :key="index">{{ item.label }}</view>
|
|
<view class="picker-item" v-for="(item, index) in days" :key="index">{{ item.label }}</view>
|
|
|
</picker-view-column>
|
|
</picker-view-column>
|
|
@@ -38,6 +38,8 @@ export default {
|
|
|
return {
|
|
return {
|
|
|
visible: false, // 控制picker-view的渲染
|
|
visible: false, // 控制picker-view的渲染
|
|
|
pickerValue: [0, 0, 0],
|
|
pickerValue: [0, 0, 0],
|
|
|
|
|
+ tempPickerValue: [0, 0, 0], // 临时存储滚动过程中的值
|
|
|
|
|
+ debounceTimer: null,
|
|
|
days: [],
|
|
days: [],
|
|
|
hours: [],
|
|
hours: [],
|
|
|
minutes: [],
|
|
minutes: [],
|
|
@@ -73,6 +75,7 @@ export default {
|
|
|
this.hours = this.generateHours(tomorrow, false);
|
|
this.hours = this.generateHours(tomorrow, false);
|
|
|
this.minutes = this.generateMinutes(tomorrow, false, this.hours[0].value);
|
|
this.minutes = this.generateMinutes(tomorrow, false, this.hours[0].value);
|
|
|
this.pickerValue = [1, 0, 0]; // Select "Tomorrow", first hour, first minute
|
|
this.pickerValue = [1, 0, 0]; // Select "Tomorrow", first hour, first minute
|
|
|
|
|
+ this.tempPickerValue = [1, 0, 0];
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -85,6 +88,7 @@ export default {
|
|
|
const initialMinuteIndex = 0;
|
|
const initialMinuteIndex = 0;
|
|
|
|
|
|
|
|
this.pickerValue = [0, initialHourIndex, initialMinuteIndex];
|
|
this.pickerValue = [0, initialHourIndex, initialMinuteIndex];
|
|
|
|
|
+ this.tempPickerValue = [0, initialHourIndex, initialMinuteIndex];
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
generateDays() {
|
|
generateDays() {
|
|
@@ -135,7 +139,20 @@ export default {
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
handleChange(e) {
|
|
handleChange(e) {
|
|
|
- const [dayIndex, hourIndex, minuteIndex] = e.detail.value;
|
|
|
|
|
|
|
+ const val = e.detail.value;
|
|
|
|
|
+ this.tempPickerValue = val;
|
|
|
|
|
+
|
|
|
|
|
+ if (this.debounceTimer) {
|
|
|
|
|
+ clearTimeout(this.debounceTimer);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.debounceTimer = setTimeout(() => {
|
|
|
|
|
+ this.updatePickers(val);
|
|
|
|
|
+ }, 100);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ updatePickers(val, isSync = false) {
|
|
|
|
|
+ const [dayIndex, hourIndex, minuteIndex] = val;
|
|
|
const oldPickerValue = this.pickerValue;
|
|
const oldPickerValue = this.pickerValue;
|
|
|
|
|
|
|
|
const now = dayjs();
|
|
const now = dayjs();
|
|
@@ -150,26 +167,46 @@ export default {
|
|
|
// Day changed
|
|
// Day changed
|
|
|
if (oldPickerValue[0] !== dayIndex) {
|
|
if (oldPickerValue[0] !== dayIndex) {
|
|
|
newHours = this.generateHours(now, isToday);
|
|
newHours = this.generateHours(now, isToday);
|
|
|
- finalHourIndex = 0;
|
|
|
|
|
|
|
+ // 修正越界,尽量保持用户的选择,而不是强制归零
|
|
|
|
|
+ if (finalHourIndex >= newHours.length) {
|
|
|
|
|
+ finalHourIndex = 0;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Hour changed (or day changed)
|
|
|
|
|
- if (oldPickerValue[0] !== dayIndex || oldPickerValue[1] !== hourIndex) {
|
|
|
|
|
- const selectedHour = newHours[finalHourIndex].value;
|
|
|
|
|
- newMinutes = this.generateMinutes(now, isToday, selectedHour);
|
|
|
|
|
- finalMinuteIndex = 0;
|
|
|
|
|
|
|
+ // Calculate selected hour based on current indices
|
|
|
|
|
+ const selectedHour = newHours[finalHourIndex] ? newHours[finalHourIndex].value : -1;
|
|
|
|
|
+
|
|
|
|
|
+ // Always regenerate minutes to ensure correctness (e.g. today/tomorrow switch, or hour switch)
|
|
|
|
|
+ // Optimization: we could check if generation parameters actually changed, but it's fast enough.
|
|
|
|
|
+ newMinutes = this.generateMinutes(now, isToday, selectedHour);
|
|
|
|
|
+
|
|
|
|
|
+ // 修正越界
|
|
|
|
|
+ if (finalMinuteIndex >= newMinutes.length) {
|
|
|
|
|
+ finalMinuteIndex = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
this.hours = newHours;
|
|
this.hours = newHours;
|
|
|
this.minutes = newMinutes;
|
|
this.minutes = newMinutes;
|
|
|
|
|
+ this.debounceTimer = null;
|
|
|
|
|
|
|
|
- // Use setTimeout to avoid visual glitch on picker reset
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- this.pickerValue = [dayIndex, finalHourIndex, finalMinuteIndex];
|
|
|
|
|
- }, 0);
|
|
|
|
|
|
|
+ const newValue = [dayIndex, finalHourIndex, finalMinuteIndex];
|
|
|
|
|
+
|
|
|
|
|
+ if (isSync) {
|
|
|
|
|
+ this.pickerValue = newValue;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Use setTimeout to avoid visual glitch on picker reset
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ this.pickerValue = newValue;
|
|
|
|
|
+ }, 0);
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
handleConfirm() {
|
|
handleConfirm() {
|
|
|
|
|
+ if (this.debounceTimer) {
|
|
|
|
|
+ clearTimeout(this.debounceTimer);
|
|
|
|
|
+ this.updatePickers(this.tempPickerValue, true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const [dayIndex, hourIndex, minuteIndex] = this.pickerValue;
|
|
const [dayIndex, hourIndex, minuteIndex] = this.pickerValue;
|
|
|
const selectedDay = this.days[dayIndex];
|
|
const selectedDay = this.days[dayIndex];
|
|
|
const selectedHour = this.hours[hourIndex];
|
|
const selectedHour = this.hours[hourIndex];
|