stellar-ui-plus 1.24.20 → 1.24.21

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,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { watch, onMounted, computed, nextTick, onUnmounted, ref, shallowRef } from 'vue';
2
+ import { watch, onMounted, computed, nextTick, onUnmounted } from 'vue';
3
3
  import { useColorStore } from '../../store/color';
4
4
  let { getColor } = useColorStore();
5
5
  import { formatDate, type DateType, type WeekType } from './date';
@@ -9,61 +9,22 @@ import useData from './useData';
9
9
  import propsData from './props';
10
10
  import { getCalendarData } from './date';
11
11
 
12
- // 类型定义
13
- interface CacheKey {
14
- minDate: DateType;
15
- maxDate: DateType;
16
- viewDate: string;
17
- monthCount: number;
18
- formatter: string;
19
- signs: string;
20
- viewStart: DateType;
21
- viewEnd: DateType;
22
- }
23
-
24
- // 缓存相关
25
- const cachedCalendarData = shallowRef<any>(null);
26
- const lastCacheKey = ref<string>('');
27
-
28
- // 定时器管理
29
- let viewTimer: ReturnType<typeof setTimeout> | null = null;
30
- let scrollTimer: ReturnType<typeof setTimeout> | null = null;
31
-
32
12
  const props = defineProps(propsData);
33
13
 
34
- // 缓存键生成函数
35
- const generateCacheKey = (): string => {
36
- const cacheKey: CacheKey = {
37
- minDate: props.minDate,
38
- maxDate: props.maxDate,
39
- viewDate: viewDate.value.format('YYYY-MM-DD'),
40
- monthCount: props.monthCount,
41
- formatter: props.formatter,
42
- signs: JSON.stringify(props.signs),
43
- viewStart: props.viewStart,
44
- viewEnd: props.viewEnd,
45
- };
46
- return JSON.stringify(cacheKey);
47
- };
48
-
49
- // 优化的计算属性 - 添加缓存机制
50
- const cmpDates = computed(() => {
51
- const currentKey = generateCacheKey();
52
-
53
- if (currentKey !== lastCacheKey.value || !cachedCalendarData.value) {
54
- cachedCalendarData.value = getCalendarData(props.minDate, props.maxDate, viewDate.value, props.monthCount, props.formatter, props.signs, props.viewStart, props.viewEnd);
55
- lastCacheKey.value = currentKey;
56
- }
57
-
58
- return cachedCalendarData.value;
59
- });
14
+ // 常量定义
15
+ const ROW_HEIGHT_WITH_SIGN = 180;
16
+ const ROW_HEIGHT_WITHOUT_SIGN = 126;
17
+ const MONTH_HEADER_HEIGHT = 80;
18
+ const VIEW_MONTH_DELAY = 50;
19
+ const SHOW_MONTH_DELAY = 100;
60
20
 
61
21
  const cmpShowSigns = computed(() => {
62
22
  return Object.keys(props.signs).length > 0;
63
23
  });
24
+ const cmpDates = computed(() => getCalendarData(props.minDate, props.maxDate, viewDate.value, props.monthCount, props.formatter, props.signs, props.viewStart, props.viewEnd));
64
25
 
65
26
  const cmpRootStyle = computed(() => {
66
- const rowHeight = cmpShowSigns.value ? utils.formatPx(180, 'num') : utils.formatPx(126, 'num');
27
+ const rowHeight = cmpShowSigns.value ? utils.formatPx(ROW_HEIGHT_WITH_SIGN, 'num') : utils.formatPx(ROW_HEIGHT_WITHOUT_SIGN, 'num');
67
28
  const color = props.color ? props.color : getColor().steThemeColor;
68
29
  return {
69
30
  '--calendar-width': utils.formatPx(props.width),
@@ -89,7 +50,7 @@ const cmpMonthTops = computed(() => {
89
50
  for (let i = 0; i < datas.length; i++) {
90
51
  const month = datas[i];
91
52
  tops[month.key] = { top: end };
92
- end += utils.formatPx(80, 'num');
53
+ end += utils.formatPx(MONTH_HEADER_HEIGHT, 'num');
93
54
  end += rowHeight * month.weeks.length;
94
55
  tops[month.key].end = end;
95
56
  }
@@ -106,49 +67,33 @@ const emits = defineEmits<{
106
67
  (e: 'view-month', month: string): void;
107
68
  }>();
108
69
 
109
- // 定时器清理函数
110
- const clearTimers = () => {
70
+ let viewTimer: ReturnType<typeof setTimeout> | null = null;
71
+ const clearViewTimer = () => {
111
72
  if (viewTimer) {
112
73
  clearTimeout(viewTimer);
113
74
  viewTimer = null;
114
75
  }
115
- if (scrollTimer) {
116
- clearTimeout(scrollTimer);
117
- scrollTimer = null;
118
- }
119
76
  };
120
77
 
121
- // 策略模式优化事件处理
122
- const modeHandlers = {
123
- single: (day: WeekType) => {
124
- setDataList([day.key]);
125
- },
126
- multiple: (day: WeekType) => {
127
- const index = dataList.value.indexOf(day.key);
128
- if (index === -1) {
129
- if (props.maxCount && dataList.value.length >= (props.maxCount as number)) return;
130
- dataList.value.push(day.key);
131
- } else {
132
- dataList.value.splice(index, 1);
133
- }
134
- },
135
- range: (day: WeekType) => {
136
- onRange(day);
137
- },
138
- };
78
+ onUnmounted(() => {
79
+ clearViewTimer();
80
+ });
139
81
 
140
82
  const showMonth = (date?: DateType) => {
141
- clearTimers();
142
83
  const newDate: Dayjs = date ? utils.dayjs(date) : viewDate.value;
143
84
  if (newDate.format('YYYY-MM-DD') !== viewDate.value.format('YYYY-MM-DD')) {
144
85
  viewDate.value = newDate;
145
86
  }
87
+ clearViewTimer();
146
88
  viewTimer = setTimeout(() => {
147
- // 如果显示的月份不在范围区间内,则显示范围区间的第一个月份或者最后一个月份
148
89
  if (props.minDate && props.maxDate) {
149
- if (utils.dayjs(viewDate.value).valueOf() < utils.dayjs(props.minDate).valueOf()) {
90
+ const viewValue = utils.dayjs(viewDate.value).valueOf();
91
+ const minValue = utils.dayjs(props.minDate).valueOf();
92
+ const maxValue = utils.dayjs(props.maxDate).valueOf();
93
+
94
+ if (viewValue < minValue) {
150
95
  viewDate.value = utils.dayjs(props.minDate);
151
- } else if (utils.dayjs(viewDate.value).valueOf() > utils.dayjs(props.maxDate).valueOf()) {
96
+ } else if (viewValue > maxValue) {
152
97
  viewDate.value = utils.dayjs(props.maxDate);
153
98
  }
154
99
  }
@@ -157,7 +102,6 @@ const showMonth = (date?: DateType) => {
157
102
  const top = tops[_viewMonth]?.top || 0;
158
103
  if (top === undefined || scrollTop.value === top) {
159
104
  initing.value = false;
160
- viewTimer = null;
161
105
  return;
162
106
  }
163
107
  contentScrollTop.value = scrollTop.value;
@@ -166,9 +110,8 @@ const showMonth = (date?: DateType) => {
166
110
  scrollTop.value = top;
167
111
  viewMonth.value = _viewMonth;
168
112
  initing.value = false;
169
- viewTimer = null;
170
113
  });
171
- }, 50);
114
+ }, VIEW_MONTH_DELAY);
172
115
  };
173
116
 
174
117
  const onMultiple = (day: WeekType) => {
@@ -186,12 +129,17 @@ const rangeDates = () => {
186
129
  const start = formatDate(startDate.value);
187
130
  const end = formatDate(endDate.value);
188
131
  let list: (string | number)[] = [];
189
- for (let i = new Date(start); i <= new Date(end); i.setDate(i.getDate() + 1)) {
190
- list.push(formatDate(i, props.formatter));
132
+
133
+ const startDateObj = new Date(start);
134
+ const endDateObj = new Date(end);
135
+ for (let i = startDateObj; i <= endDateObj; i.setDate(i.getDate() + 1)) {
136
+ list.push(formatDate(new Date(i), props.formatter));
191
137
  }
138
+
192
139
  if (list.length < 2) {
193
140
  list = [startDate.value, endDate.value];
194
141
  }
142
+
195
143
  if (props.maxRange !== null && list.length > props.maxRange) {
196
144
  setEndDate(null);
197
145
  if (props.showRangePrompt) {
@@ -226,50 +174,41 @@ const onRange = (day: WeekType) => {
226
174
 
227
175
  const onSelect = (day: WeekType) => {
228
176
  if (props.readonly || !day.dayText || day.disabled) return;
229
-
230
- const handler = modeHandlers[props.mode as keyof typeof modeHandlers];
231
- if (handler) {
232
- handler(day);
233
- emits('select', dataList.value, day.key);
234
- }
235
- };
236
-
237
- // 统一初始化逻辑
238
- const initializeRangeMode = () => {
239
- if (dataList.value.length >= 2) {
240
- startDate.value = dataList.value[0];
241
- endDate.value = dataList.value[dataList.value.length - 1];
242
- } else if (dataList.value.length === 1) {
243
- startDate.value = endDate.value = dataList.value[0];
244
- } else {
245
- startDate.value = endDate.value = null;
246
- }
247
- rangeDates();
248
- };
249
-
250
- const initializeCalendar = () => {
251
- // 初始化视图日期
252
- viewDate.value = props.defaultDate ? utils.dayjs(props.defaultDate) : utils.dayjs();
253
-
254
- // 初始化选中数据
255
- dataList.value = (props.list || []).map(d => formatDate(d, props.formatter));
256
-
257
- // 处理范围模式的特殊逻辑
258
- if (props.mode === 'range') {
259
- initializeRangeMode();
177
+ if (props.mode === 'single') {
178
+ setDataList([day.key]);
179
+ } else if (props.mode === 'multiple') {
180
+ onMultiple(day);
181
+ } else if (props.mode === 'range') {
182
+ onRange(day);
260
183
  }
261
-
262
- // 显示月份
263
- nextTick(() => {
264
- showMonth();
265
- });
184
+ emits('select', dataList.value, day.key);
266
185
  };
267
186
 
268
- // 简化的watch逻辑
269
187
  watch(
270
- () => [props.list, props.defaultDate, props.mode],
271
- () => {
272
- initializeCalendar();
188
+ () => props.list,
189
+ v => {
190
+ dataList.value = (v || []).map(d => formatDate(d, props.formatter));
191
+ if (props.mode === 'range') {
192
+ if (dataList.value.length >= 2) {
193
+ startDate.value = dataList.value[0];
194
+ endDate.value = dataList.value[dataList.value.length - 1];
195
+ } else if (dataList.value.length === 1) {
196
+ startDate.value = dataList.value[0];
197
+ endDate.value = dataList.value[0];
198
+ } else {
199
+ startDate.value = null;
200
+ endDate.value = null;
201
+ }
202
+ rangeDates();
203
+ }
204
+ },
205
+ { immediate: true }
206
+ );
207
+ watch(
208
+ () => props.defaultDate,
209
+ v => {
210
+ viewDate.value = v ? utils.dayjs(v) : utils.dayjs();
211
+ showMonth();
273
212
  },
274
213
  { immediate: true }
275
214
  );
@@ -277,43 +216,30 @@ watch(
277
216
  const confirm = () => {
278
217
  emits('confirm', dataList.value);
279
218
  };
280
-
281
219
  onMounted(() => {
282
- initializeCalendar();
283
- });
284
-
285
- // 组件销毁时清理资源
286
- onUnmounted(() => {
287
- clearTimers();
220
+ showMonth();
288
221
  });
289
222
 
290
223
  defineExpose({ showMonth });
291
-
292
224
  const onShowMonth = (scrollTop: number) => {
293
- clearTimers();
294
- scrollTimer = setTimeout(() => {
225
+ clearViewTimer();
226
+ viewTimer = setTimeout(() => {
295
227
  for (let month in cmpMonthTops.value) {
296
228
  const { top = 0, end = 0 } = cmpMonthTops.value[month];
297
229
  if (scrollTop >= top && scrollTop < end) {
298
- if (viewMonth.value === month) {
299
- scrollTimer = null;
300
- return;
301
- }
230
+ if (viewMonth.value === month) return;
302
231
  viewMonth.value = month;
303
232
  emits('view-month', month);
304
- scrollTimer = null;
305
233
  return;
306
234
  }
307
235
  }
308
- }, 150);
236
+ }, SHOW_MONTH_DELAY);
309
237
  };
310
-
311
238
  const onScroll = (e: any) => {
312
239
  scrollTop.value = e.detail.scrollTop;
313
240
  onShowMonth(e.detail.scrollTop);
314
241
  };
315
242
  </script>
316
-
317
243
  <template>
318
244
  <view class="ste-calendar-root" :style="[cmpRootStyle, { opacity: initing ? 0 : 1 }]">
319
245
  <view v-if="showTitle" class="calendar-title">{{ title }}</view>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stellar-ui-plus",
3
- "version": "1.24.20",
3
+ "version": "1.24.21",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "license": "MIT",