@tdesign/uniapp 0.7.3 → 0.8.0

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.
Files changed (197) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +1 -1
  3. package/dist/action-sheet/README.md +1 -1
  4. package/dist/action-sheet/action-sheet.vue +158 -150
  5. package/dist/action-sheet/props.ts +2 -2
  6. package/dist/action-sheet/type.ts +1 -1
  7. package/dist/avatar/avatar.vue +89 -87
  8. package/dist/avatar-group/avatar-group.vue +69 -67
  9. package/dist/back-top/back-top.vue +60 -58
  10. package/dist/badge/badge.vue +69 -59
  11. package/dist/button/button.vue +121 -116
  12. package/dist/button/props.ts +2 -2
  13. package/dist/button/type.ts +1 -1
  14. package/dist/calendar/calendar-header.vue +4 -4
  15. package/dist/calendar/calendar.vue +308 -297
  16. package/dist/calendar/template.vue +1 -1
  17. package/dist/cascader/README.en-US.md +2 -1
  18. package/dist/cascader/README.md +2 -1
  19. package/dist/cascader/cascader.vue +340 -328
  20. package/dist/cascader/props.ts +6 -1
  21. package/dist/cascader/type.ts +6 -0
  22. package/dist/cell/cell.vue +127 -121
  23. package/dist/cell-group/cell-group.vue +32 -30
  24. package/dist/check-tag/check-tag.vue +73 -71
  25. package/dist/checkbox/checkbox.vue +127 -127
  26. package/dist/checkbox/props.ts +6 -6
  27. package/dist/checkbox/type.ts +3 -3
  28. package/dist/checkbox-group/checkbox-group.vue +175 -173
  29. package/dist/checkbox-group/props.ts +6 -6
  30. package/dist/checkbox-group/type.ts +4 -4
  31. package/dist/col/col.vue +26 -24
  32. package/dist/collapse/collapse.vue +83 -81
  33. package/dist/collapse-panel/collapse-panel.vue +121 -119
  34. package/dist/collapse-panel/props.ts +4 -4
  35. package/dist/collapse-panel/type.ts +2 -2
  36. package/dist/color-picker/README.md +1 -1
  37. package/dist/color-picker/color-picker.vue +324 -322
  38. package/dist/color-picker/props.ts +2 -2
  39. package/dist/color-picker/template.vue +14 -10
  40. package/dist/common/common.ts +1 -0
  41. package/dist/common/style/theme/index.css +5 -5
  42. package/dist/common/utils.js +7 -2
  43. package/dist/common/validator.js +172 -0
  44. package/dist/config-provider/README.en-US.md +184 -0
  45. package/dist/config-provider/README.md +234 -0
  46. package/dist/config-provider/config-provider.vue +105 -0
  47. package/dist/config-provider/config-store.js +70 -0
  48. package/dist/config-provider/props.ts +16 -0
  49. package/dist/config-provider/reactive-state.js +39 -0
  50. package/dist/config-provider/type.ts +401 -0
  51. package/dist/config-provider/use-config.js +29 -0
  52. package/dist/config-provider/utils.js +29 -0
  53. package/dist/count-down/count-down.vue +98 -97
  54. package/dist/date-time-picker/date-time-picker.vue +410 -395
  55. package/dist/demo/demo.vue +1 -0
  56. package/dist/dialog/dialog.vue +175 -173
  57. package/dist/divider/divider.vue +38 -36
  58. package/dist/draggable/draggable.vue +60 -58
  59. package/dist/drawer/README.md +1 -1
  60. package/dist/drawer/drawer.vue +48 -46
  61. package/dist/dropdown-item/dropdown-item.vue +209 -207
  62. package/dist/dropdown-item/props.ts +4 -4
  63. package/dist/dropdown-item/type.ts +3 -3
  64. package/dist/dropdown-menu/dropdown-menu.vue +93 -99
  65. package/dist/empty/empty.vue +43 -42
  66. package/dist/fab/fab.vue +88 -86
  67. package/dist/footer/footer.vue +36 -34
  68. package/dist/form/README.en-US.md +17 -24
  69. package/dist/form/README.md +18 -25
  70. package/dist/form/form.css +1 -166
  71. package/dist/form/form.vue +251 -236
  72. package/dist/form/props.ts +2 -21
  73. package/dist/form/type.ts +7 -70
  74. package/dist/form-item/README.en-US.md +4 -5
  75. package/dist/form-item/README.md +4 -5
  76. package/dist/form-item/form-item.css +69 -96
  77. package/dist/form-item/form-item.vue +315 -336
  78. package/dist/form-item/form-model.ts +125 -173
  79. package/dist/form-item/props.ts +4 -17
  80. package/dist/form-item/type.ts +43 -1
  81. package/dist/grid/grid.vue +53 -51
  82. package/dist/grid-item/grid-item.vue +121 -119
  83. package/dist/guide/README.md +1 -1
  84. package/dist/guide/guide.vue +281 -277
  85. package/dist/icon/README.md +2 -4
  86. package/dist/icon/icon.vue +78 -76
  87. package/dist/image/README.md +1 -1
  88. package/dist/image/image.vue +103 -101
  89. package/dist/image-viewer/image-viewer.vue +160 -158
  90. package/dist/image-viewer/props.ts +2 -2
  91. package/dist/image-viewer/type.ts +1 -1
  92. package/dist/index.js +3 -0
  93. package/dist/indexes/indexes.vue +264 -267
  94. package/dist/indexes-anchor/indexes-anchor.vue +41 -41
  95. package/dist/input/input.vue +192 -192
  96. package/dist/input/props.ts +6 -6
  97. package/dist/input/type.ts +3 -3
  98. package/dist/link/link.vue +73 -71
  99. package/dist/loading/loading.vue +59 -59
  100. package/dist/locale/ar_KW.ts +157 -0
  101. package/dist/locale/en_US.ts +146 -0
  102. package/dist/locale/it_IT.ts +145 -0
  103. package/dist/locale/ja_JP.ts +132 -0
  104. package/dist/locale/ko_KR.ts +132 -0
  105. package/dist/locale/ru_RU.ts +157 -0
  106. package/dist/locale/zh_CN.ts +133 -0
  107. package/dist/locale/zh_TW.ts +132 -0
  108. package/dist/message/message.vue +181 -173
  109. package/dist/message/props.ts +2 -2
  110. package/dist/message/type.ts +1 -1
  111. package/dist/message-item/message-item.vue +192 -184
  112. package/dist/mixins/using-config.js +39 -0
  113. package/dist/navbar/navbar.vue +201 -199
  114. package/dist/notice-bar/notice-bar.vue +175 -171
  115. package/dist/notice-bar/props.ts +2 -2
  116. package/dist/notice-bar/type.ts +1 -1
  117. package/dist/npm/dayjs/esm/locale/ar.js +81 -0
  118. package/dist/npm/dayjs/esm/locale/it.js +39 -0
  119. package/dist/overlay/overlay.vue +50 -48
  120. package/dist/picker/picker.vue +168 -161
  121. package/dist/picker-item/picker-item.vue +269 -269
  122. package/dist/popover/README.md +1 -1
  123. package/dist/popover/popover.vue +262 -261
  124. package/dist/popover/props.ts +4 -4
  125. package/dist/popover/type.ts +2 -2
  126. package/dist/popup/popup.vue +46 -45
  127. package/dist/progress/README.md +1 -1
  128. package/dist/progress/progress.vue +76 -76
  129. package/dist/pull-down-refresh/props.ts +2 -2
  130. package/dist/pull-down-refresh/pull-down-refresh.vue +240 -234
  131. package/dist/pull-down-refresh/type.ts +1 -1
  132. package/dist/qrcode/README.md +1 -1
  133. package/dist/qrcode/components/qrcode-canvas/qrcode-canvas.vue +340 -338
  134. package/dist/qrcode/components/qrcode-status/qrcode-status.vue +6 -6
  135. package/dist/qrcode/qrcode.vue +93 -87
  136. package/dist/radio/props.ts +6 -6
  137. package/dist/radio/radio.vue +118 -120
  138. package/dist/radio/type.ts +3 -3
  139. package/dist/radio-group/props.ts +4 -4
  140. package/dist/radio-group/radio-group.vue +136 -134
  141. package/dist/radio-group/type.ts +4 -4
  142. package/dist/rate/computed.js +2 -2
  143. package/dist/rate/props.ts +4 -4
  144. package/dist/rate/rate.vue +155 -154
  145. package/dist/rate/type.ts +2 -2
  146. package/dist/result/result.vue +41 -39
  147. package/dist/row/row.vue +38 -36
  148. package/dist/scroll-view/scroll-view.vue +24 -22
  149. package/dist/search/props.ts +2 -2
  150. package/dist/search/search.vue +127 -125
  151. package/dist/search/type.ts +1 -1
  152. package/dist/side-bar/side-bar.vue +57 -55
  153. package/dist/side-bar-item/side-bar-item.vue +86 -86
  154. package/dist/skeleton/skeleton.vue +126 -124
  155. package/dist/slider/README.md +1 -1
  156. package/dist/slider/props.ts +2 -2
  157. package/dist/slider/slider.vue +457 -457
  158. package/dist/slider/type.ts +1 -1
  159. package/dist/step-item/step-item.vue +77 -75
  160. package/dist/stepper/props.ts +2 -2
  161. package/dist/stepper/stepper.vue +168 -149
  162. package/dist/stepper/type.ts +1 -1
  163. package/dist/steps/props.ts +2 -2
  164. package/dist/steps/steps.vue +83 -81
  165. package/dist/steps/type.ts +1 -1
  166. package/dist/sticky/sticky.vue +104 -102
  167. package/dist/swipe-cell/swipe-cell.vue +91 -89
  168. package/dist/swiper/README.md +1 -1
  169. package/dist/swiper/swiper.vue +91 -89
  170. package/dist/swiper-nav/swiper-nav.vue +38 -36
  171. package/dist/switch/props.ts +2 -2
  172. package/dist/switch/switch.vue +62 -62
  173. package/dist/switch/type.ts +1 -1
  174. package/dist/tab-bar/tab-bar.vue +88 -86
  175. package/dist/tab-bar-item/tab-bar-item.vue +85 -82
  176. package/dist/tab-panel/tab-panel.vue +66 -64
  177. package/dist/tabs/tabs.vue +294 -287
  178. package/dist/tag/tag.vue +79 -77
  179. package/dist/textarea/props.ts +6 -6
  180. package/dist/textarea/textarea.vue +127 -126
  181. package/dist/textarea/type.ts +3 -3
  182. package/dist/toast/toast.vue +107 -106
  183. package/dist/transition/transition.vue +30 -28
  184. package/dist/tree-select/tree-select.vue +151 -151
  185. package/dist/types/config-provider.d.ts +7 -0
  186. package/dist/types/index.d.ts +2 -0
  187. package/dist/types/popover.d.ts +7 -0
  188. package/dist/upload/README.en-US.md +13 -14
  189. package/dist/upload/README.md +11 -12
  190. package/dist/upload/props.ts +2 -4
  191. package/dist/upload/type.ts +12 -11
  192. package/dist/upload/upload.css +1 -1
  193. package/dist/upload/upload.vue +672 -512
  194. package/dist/watermark/watermark.vue +151 -149
  195. package/global.d.ts +2 -0
  196. package/package.json +15 -3
  197. package/dist/form/form-item-props.ts +0 -56
@@ -6,10 +6,10 @@
6
6
  :visible="visible"
7
7
  :value="columnsValue"
8
8
  :header="header"
9
- :title="title"
9
+ :title="title || globalConfig.title || ''"
10
10
  :auto-close="autoClose"
11
- :confirm-btn="confirmBtn || locale.confirm"
12
- :cancel-btn="cancelBtn || locale.cancel"
11
+ :confirm-btn="confirmBtn || globalConfig.confirm"
12
+ :cancel-btn="cancelBtn || globalConfig.cancel"
13
13
  :use-popup="usePopup"
14
14
  :popup-props="popupProps"
15
15
  @pick="onColumnChange"
@@ -29,7 +29,7 @@
29
29
  <t-picker-item
30
30
  v-for="(item, index) in columns"
31
31
  :key="index"
32
- :class="tools.cls(classPrefix + '__item', [['roomly', columns.length >= 5 && index == 0]])"
32
+ :class="[classPrefix + '__item', columns.length >= 5 && index == 0 ? classPrefix + '__item' + '--roomly' : '']"
33
33
  :use-slots="false"
34
34
  :options="item"
35
35
  index="index"
@@ -57,6 +57,7 @@ import tools from '../common/utils.wxs';
57
57
  import dayjs from '../npm/dayjs/esm/index.js';
58
58
  import localeData from '../npm/dayjs/esm/plugin/localeData';
59
59
 
60
+ import usingConfig from '../mixins/using-config';
60
61
  /**
61
62
  * dayjs LocaleData 插件
62
63
  * https://dayjs.fenxianglu.cn/category/plugin.html#localedata
@@ -67,7 +68,8 @@ dayjs.locale('zh-cn');
67
68
  const defaultLocale = dayjsLocaleMap[dayjs.locale()]?.key || dayjsLocaleMap.default?.key;
68
69
 
69
70
 
70
- const name = `${prefix}-date-time-picker`;
71
+ const componentName = 'date-time-picker';
72
+ const name = `${prefix}-${componentName}`;
71
73
 
72
74
  const ModeItem = {
73
75
  YEAR: 'year',
@@ -82,487 +84,500 @@ const DATE_MODES = ['year', 'month', 'date'];
82
84
  const TIME_MODES = ['hour', 'minute', 'second'];
83
85
  const FULL_MODES = [...DATE_MODES, ...TIME_MODES];
84
86
 
85
- export default uniComponent({
86
- name,
87
- options: {
88
- styleIsolation: 'shared',
89
- },
90
- controlledProps: [
91
- {
92
- key: 'value',
93
- event: 'change',
94
- },
95
- ],
96
- externalClasses: [
97
- `${prefix}-class`,
98
- `${prefix}-class-confirm`,
99
- `${prefix}-class-cancel`,
100
- `${prefix}-class-title`,
101
- ],
87
+ export default {
102
88
  components: {
103
89
  TPicker,
104
90
  TPickerItem,
105
91
  },
106
- props: {
107
- ...props,
108
- },
109
- emits: [
110
- 'update:visible',
111
- ],
112
- data() {
113
- return {
114
- prefix,
115
- classPrefix: name,
116
- columns: [],
117
- columnsValue: [],
118
- fullModes: [],
119
- locale: dayjsLocaleMap[defaultLocale].i18n, // 国际化语言包
120
- dayjsLocale: dayjsLocaleMap[defaultLocale].key, // dayjs 自适应的 key
121
- tools,
122
-
123
- dataValue: coalesce(this.value, this.defaultValue),
124
-
125
- date: null,
126
- };
127
- },
128
- watch: {
129
- value: {
130
- handler(v) {
131
- this.dataValue = v;
92
+ ...uniComponent({
93
+ name,
94
+ mixins: [usingConfig({ componentName })],
95
+ options: {
96
+ styleIsolation: 'shared',
97
+ },
98
+ controlledProps: [
99
+ {
100
+ key: 'value',
101
+ event: 'change',
132
102
  },
133
- immediate: true,
134
- deep: true,
103
+ ],
104
+ externalClasses: [
105
+ `${prefix}-class`,
106
+ `${prefix}-class-confirm`,
107
+ `${prefix}-class-cancel`,
108
+ `${prefix}-class-title`,
109
+ ],
110
+ props: {
111
+ ...props,
112
+ },
113
+ emits: [
114
+ 'update:visible',
115
+ ],
116
+ data() {
117
+ return {
118
+ prefix,
119
+ classPrefix: name,
120
+ columns: [],
121
+ columnsValue: [],
122
+ fullModes: [],
123
+ locale: dayjsLocaleMap[defaultLocale].i18n, // 国际化语言包
124
+ dayjsLocale: dayjsLocaleMap[defaultLocale].key, // dayjs 自适应的 key
125
+ tools,
126
+
127
+ dataValue: coalesce(this.value, this.defaultValue),
128
+
129
+ date: null,
130
+ };
135
131
  },
132
+ watch: {
133
+ value: {
134
+ handler(v) {
135
+ this.dataValue = v;
136
+ },
137
+ immediate: true,
138
+ deep: true,
139
+ },
136
140
 
137
- start: 'updateColumns',
138
- end: 'updateColumns',
139
- dataValue: 'updateColumns',
140
-
141
- customLocale: {
142
- handler(v) {
143
- if (!v || !dayjsLocaleMap[v].key) return;
144
- this.locale = dayjsLocaleMap[v].i18n;
145
- this.dayjsLocale = dayjsLocaleMap[v].key;
141
+ start: 'updateColumns',
142
+ end: 'updateColumns',
143
+ dataValue: 'updateColumns',
144
+
145
+ customLocale: {
146
+ handler(v) {
147
+ if (!v || !dayjsLocaleMap[v].key) return;
148
+ this.locale = dayjsLocaleMap[v].i18n;
149
+ this.dayjsLocale = dayjsLocaleMap[v].key;
150
+ },
151
+ immediate: true,
146
152
  },
147
- immediate: true,
148
- },
149
153
 
150
- mode: {
151
- handler(v, prev) {
154
+ mode: {
155
+ handler(v, prev) {
152
156
  // 解决 pick 事件触发两次问题
153
- const checkEqual = () => {
154
- if (!prev) return false;
155
- let result = false;
156
- try {
157
- result = JSON.stringify(v) === JSON.stringify(prev);
158
- } catch (e) {
157
+ const checkEqual = () => {
158
+ if (!prev) return false;
159
+ let result = false;
160
+ try {
161
+ result = JSON.stringify(v) === JSON.stringify(prev);
162
+ } catch (e) {
163
+ return result;
164
+ }
159
165
  return result;
160
- }
161
- return result;
162
- };
163
- if (checkEqual()) return;
164
-
165
- const fullModes = this.getFullModeArray(v);
166
- this.fullModes = fullModes;
167
- this.updateColumns();
166
+ };
167
+ if (checkEqual()) return;
168
+
169
+ const fullModes = this.getFullModeArray(v);
170
+ this.fullModes = fullModes;
171
+ this.updateColumns();
172
+ },
173
+ immediate: true,
168
174
  },
169
- immediate: true,
170
175
  },
171
- },
172
- created() {
176
+ created() {
173
177
  // created 时机并不准,uniapp 自己 mock 的
174
178
  // this.date = null;
175
- },
176
- mounted() {
177
-
178
- },
179
- methods: {
180
- updateColumns() {
181
- this.date = this.getParseDate();
179
+ },
180
+ mounted() {
182
181
 
183
- const { columns, columnsValue } = this.getValueCols();
184
- this.columns = columns,
185
- this.columnsValue = columnsValue;
186
182
  },
183
+ methods: {
184
+ updateColumns() {
185
+ this.date = this.getParseDate();
187
186
 
188
- getDaysOfWeekInMonth(date, type) {
189
- const { locale, steps, dayjsLocale } = this;
190
- const startOfMonth = date.startOf('month');
191
- const minEdge = this.getOptionEdge('min', type);
192
- const maxEdge = this.getOptionEdge('max', type);
193
- const step = coalesce(steps?.[type], 1);
194
- const daysOfWeek = [];
195
-
196
- for (let i = minEdge; i <= maxEdge; i += step) {
197
- const currentDate = startOfMonth.date(i).locale(dayjsLocale);
198
- const dayName = currentDate.format('ddd');
199
- daysOfWeek.push({
200
- value: `${i}`,
201
- label: `${i}${locale.date || ''} ${dayName}`,
202
- });
203
- }
187
+ const { columns, columnsValue } = this.getValueCols();
188
+ this.columns = columns,
189
+ this.columnsValue = columnsValue;
190
+ },
204
191
 
205
- return daysOfWeek;
206
- },
192
+ getDaysOfWeekInMonth(date, type) {
193
+ const { locale, steps, dayjsLocale } = this;
194
+ const startOfMonth = date.startOf('month');
195
+ const minEdge = this.getOptionEdge('min', type);
196
+ const maxEdge = this.getOptionEdge('max', type);
197
+ const step = coalesce(steps?.[type], 1);
198
+ const daysOfWeek = [];
199
+
200
+ for (let i = minEdge; i <= maxEdge; i += step) {
201
+ const currentDate = startOfMonth.date(i).locale(dayjsLocale);
202
+ const dayName = currentDate.format('ddd');
203
+ daysOfWeek.push({
204
+ value: `${i}`,
205
+ label: `${i}${locale.date || ''} ${dayName}`,
206
+ });
207
+ }
207
208
 
208
- getParseDate() {
209
- const { dataValue } = this;
210
- const minDate = this.getMinDate();
209
+ return daysOfWeek;
210
+ },
211
211
 
212
- const isTimeMode = this.isTimeMode();
213
- let currentValue = dataValue;
212
+ getParseDate() {
213
+ const { dataValue } = this;
214
+ const minDate = this.getMinDate();
214
215
 
215
- // 时间需要补齐前缀
216
- if (isTimeMode) {
217
- const dateStr = dayjs(minDate).format('YYYY-MM-DD');
218
- currentValue = dayjs(`${dateStr} ${currentValue}`);
219
- }
216
+ const isTimeMode = this.isTimeMode();
217
+ let currentValue = dataValue;
220
218
 
221
- const parseDate = dayjs(currentValue || minDate);
222
- const isDateValid = parseDate.isValid();
219
+ // 时间需要补齐前缀
220
+ if (isTimeMode) {
221
+ const dateStr = dayjs(minDate).format('YYYY-MM-DD');
222
+ currentValue = dayjs(`${dateStr} ${currentValue}`);
223
+ }
223
224
 
224
- return isDateValid ? parseDate : minDate;
225
- },
225
+ let parseDate = dayjs(currentValue || minDate);
226
226
 
227
- normalize(val, defaultDay) {
228
- return val && dayjs(val).isValid() ? dayjs(val) : defaultDay;
229
- },
227
+ // 当直接解析失败时(如 "2021-12-23 周四"),尝试提取日期时间数字部分进行解析
228
+ if (!parseDate.isValid() && typeof currentValue === 'string') {
229
+ // 匹配常见的日期时间格式:YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss 等
230
+ const dateMatch = currentValue.match(/(\d{4}[-/]\d{1,2}[-/]\d{1,2}(\s+\d{1,2}:\d{1,2}(:\d{1,2})?)?)/);
231
+ if (dateMatch) {
232
+ parseDate = dayjs(dateMatch[1]);
233
+ }
234
+ }
230
235
 
231
- getMinDate() {
232
- return this.normalize(this.start, dayjs().subtract(10, 'year'));
233
- },
236
+ const isDateValid = parseDate.isValid();
234
237
 
235
- getMaxDate() {
236
- return this.normalize(this.end, dayjs().add(10, 'year'));
237
- },
238
+ return isDateValid ? parseDate : minDate;
239
+ },
238
240
 
239
- getDateRect(type = 'default') {
240
- const map = {
241
- min: 'getMinDate',
242
- max: 'getMaxDate',
243
- default: 'getDate',
244
- };
245
- const date = this[map[type]]();
246
- const keys = ['year', 'month', 'date', 'hour', 'minute', 'second'];
241
+ normalize(val, defaultDay) {
242
+ return val && dayjs(val).isValid() ? dayjs(val) : defaultDay;
243
+ },
247
244
 
248
- return keys.map(k => date[k]?.());
249
- },
245
+ getMinDate() {
246
+ return this.normalize(this.start, dayjs().subtract(10, 'year'));
247
+ },
250
248
 
251
- getDate() {
252
- return this.clipDate(this?.date || this.getMinDate());
253
- },
249
+ getMaxDate() {
250
+ return this.normalize(this.end, dayjs().add(10, 'year'));
251
+ },
254
252
 
255
- // 数据裁减 确保数据不越界
256
- clipDate(date) {
257
- const minDate = this.getMinDate();
258
- const maxDate = this.getMaxDate();
259
- return dayjs(Math.min(Math.max(minDate.valueOf(), date.valueOf()), maxDate.valueOf()));
260
- },
253
+ getDateRect(type = 'default') {
254
+ const map = {
255
+ min: 'getMinDate',
256
+ max: 'getMaxDate',
257
+ default: 'getDate',
258
+ };
259
+ const date = this[map[type]]();
260
+ const keys = ['year', 'month', 'date', 'hour', 'minute', 'second'];
261
261
 
262
- // 年变化时 需要修正 日数据 例如 2 月的 28 | 29
263
- setYear(date, year) {
264
- const beforeMonthDays = date.date();
265
- const afterMonthDays = date.year(year).daysInMonth();
262
+ return keys.map(k => date[k]?.());
263
+ },
266
264
 
267
- const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf()));
268
- return tempDate.year(year);
269
- },
265
+ getDate() {
266
+ return this.clipDate(this?.date || this.getMinDate());
267
+ },
270
268
 
271
- // 月变化时 需要修正 日数据边界
272
- setMonth(date, month) {
273
- const beforeMonthDays = date.date();
274
- const afterMonthDays = date.month(month).daysInMonth();
269
+ // 数据裁减 确保数据不越界
270
+ clipDate(date) {
271
+ const minDate = this.getMinDate();
272
+ const maxDate = this.getMaxDate();
273
+ return dayjs(Math.min(Math.max(minDate.valueOf(), date.valueOf()), maxDate.valueOf()));
274
+ },
275
275
 
276
- const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf()));
277
- return tempDate.month(month);
278
- },
276
+ // 年变化时 需要修正 日数据 例如 2 月的 28 | 29
277
+ setYear(date, year) {
278
+ const beforeMonthDays = date.date();
279
+ const afterMonthDays = date.year(year).daysInMonth();
279
280
 
280
- getColumnOptions() {
281
- const { fullModes, filter } = this;
281
+ const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf()));
282
+ return tempDate.year(year);
283
+ },
282
284
 
283
- const columnOptions = [];
284
- fullModes?.forEach((mode) => {
285
- const columnOption = this.getOptionByType(mode);
286
- if (typeof filter === 'function') {
287
- columnOptions.push(filter(mode, columnOption));
288
- } else {
289
- columnOptions.push(columnOption);
290
- }
291
- });
292
- return columnOptions;
293
- },
285
+ // 月变化时 需要修正 日数据边界
286
+ setMonth(date, month) {
287
+ const beforeMonthDays = date.date();
288
+ const afterMonthDays = date.month(month).daysInMonth();
289
+
290
+ const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf()));
291
+ return tempDate.month(month);
292
+ },
293
+
294
+ getColumnOptions() {
295
+ const { fullModes, filter } = this;
294
296
 
295
- getOptionByType(type) {
296
- const { locale, steps, showWeek } = this;
297
- const options = [];
298
-
299
- const minEdge = this.getOptionEdge('min', type);
300
- const maxEdge = this.getOptionEdge('max', type);
301
- const step = coalesce(steps?.[type], 1);
302
- const dayjsMonthsShort = dayjs().locale(this.dayjsLocale)
303
- .localeData()
304
- .monthsShort();
305
-
306
- if (type === 'date' && showWeek) {
307
- return this.getDaysOfWeekInMonth(this.date, type);
308
- }
309
-
310
- for (let i = minEdge; i <= maxEdge; i += step) {
311
- options.push({
312
- value: `${i}`,
313
- label: type === 'month' ? dayjsMonthsShort[i] : `${i + locale[type]}`,
297
+ const columnOptions = [];
298
+ fullModes?.forEach((mode) => {
299
+ const columnOption = this.getOptionByType(mode);
300
+ if (typeof filter === 'function') {
301
+ columnOptions.push(filter(mode, columnOption));
302
+ } else {
303
+ columnOptions.push(columnOption);
304
+ }
314
305
  });
315
- }
306
+ return columnOptions;
307
+ },
316
308
 
317
- return options;
318
- },
309
+ getOptionByType(type) {
310
+ const { locale, steps, showWeek } = this;
311
+ const options = [];
319
312
 
320
- getYearOptions(dateParams) {
321
- const { locale } = this;
322
- const { minDateYear, maxDateYear } = dateParams;
313
+ const minEdge = this.getOptionEdge('min', type);
314
+ const maxEdge = this.getOptionEdge('max', type);
315
+ const step = coalesce(steps?.[type], 1);
316
+ const dayjsMonthsShort = dayjs().locale(this.dayjsLocale)
317
+ .localeData()
318
+ .monthsShort();
323
319
 
324
- const years = [];
325
- for (let i = minDateYear; i <= maxDateYear; i += 1) {
326
- years.push({
327
- value: `${i}`,
328
- label: `${i + locale.year}`,
329
- });
330
- }
331
- return years;
332
- },
320
+ if (type === 'date' && showWeek) {
321
+ return this.getDaysOfWeekInMonth(this.date, type);
322
+ }
333
323
 
334
- getOptionEdge(minOrMax, type) {
335
- const selDateArray = this.getDateRect();
336
- const compareArray = this.getDateRect(minOrMax);
337
- const edge = {
338
- month: [0, 11],
339
- date: [1, this.getDate().daysInMonth()],
340
- hour: [0, 23],
341
- minute: [0, 59],
342
- second: [0, 59],
343
- };
344
- const types = ['year', 'month', 'date', 'hour', 'minute', 'second'];
324
+ for (let i = minEdge; i <= maxEdge; i += step) {
325
+ options.push({
326
+ value: `${i}`,
327
+ label: type === 'month' ? dayjsMonthsShort[i] : `${i + locale[type]}`,
328
+ });
329
+ }
345
330
 
346
- for (let i = 0, size = selDateArray.length; i < size; i += 1) {
347
- if (types[i] === type) return compareArray[i];
348
- if (compareArray[i] !== selDateArray[i]) return edge[type][minOrMax === 'min' ? 0 : 1];
349
- }
350
- return edge[type][minOrMax === 'min' ? 0 : 1];
351
- },
331
+ return options;
332
+ },
352
333
 
353
- getMonthOptions() {
354
- const months = [];
334
+ getYearOptions(dateParams) {
335
+ const { locale } = this;
336
+ const { minDateYear, maxDateYear } = dateParams;
355
337
 
356
- const minMonth = this.getOptionEdge('min', 'month');
357
- const maxMonth = this.getOptionEdge('max', 'month');
358
- const dayjsMonthsShort = dayjs.monthsShort();
338
+ const years = [];
339
+ for (let i = minDateYear; i <= maxDateYear; i += 1) {
340
+ years.push({
341
+ value: `${i}`,
342
+ label: `${i + locale.year}`,
343
+ });
344
+ }
345
+ return years;
346
+ },
359
347
 
360
- for (let i = minMonth; i <= maxMonth; i += 1) {
361
- months.push({
362
- value: `${i}`,
363
- label: dayjsMonthsShort[i],
364
- });
365
- }
348
+ getOptionEdge(minOrMax, type) {
349
+ const selDateArray = this.getDateRect();
350
+ const compareArray = this.getDateRect(minOrMax);
351
+ const edge = {
352
+ month: [0, 11],
353
+ date: [1, this.getDate().daysInMonth()],
354
+ hour: [0, 23],
355
+ minute: [0, 59],
356
+ second: [0, 59],
357
+ };
358
+ const types = ['year', 'month', 'date', 'hour', 'minute', 'second'];
366
359
 
367
- return months;
368
- },
360
+ for (let i = 0, size = selDateArray.length; i < size; i += 1) {
361
+ if (types[i] === type) return compareArray[i];
362
+ if (compareArray[i] !== selDateArray[i]) return edge[type][minOrMax === 'min' ? 0 : 1];
363
+ }
364
+ return edge[type][minOrMax === 'min' ? 0 : 1];
365
+ },
369
366
 
370
- getDayOptions() {
371
- const { locale } = this;
372
- const days = [];
373
- const minDay = this.getOptionEdge('min', 'date');
374
- const maxDay = this.getOptionEdge('max', 'date');
367
+ getMonthOptions() {
368
+ const months = [];
375
369
 
376
- for (let i = minDay; i <= maxDay; i += 1) {
377
- days.push({
378
- value: `${i}`,
379
- label: `${i + locale.day}`,
380
- });
381
- }
370
+ const minMonth = this.getOptionEdge('min', 'month');
371
+ const maxMonth = this.getOptionEdge('max', 'month');
372
+ const dayjsMonthsShort = dayjs.monthsShort();
382
373
 
383
- return days;
384
- },
374
+ for (let i = minMonth; i <= maxMonth; i += 1) {
375
+ months.push({
376
+ value: `${i}`,
377
+ label: dayjsMonthsShort[i],
378
+ });
379
+ }
385
380
 
386
- getHourOptions() {
387
- const { locale } = this;
388
- const hours = [];
389
- const minHour = this.getOptionEdge('min', 'hour');
390
- const maxHour = this.getOptionEdge('max', 'hour');
381
+ return months;
382
+ },
391
383
 
392
- for (let i = minHour; i <= maxHour; i += 1) {
393
- hours.push({
394
- value: `${i}`,
395
- label: `${i + locale.hour}`,
396
- });
397
- }
384
+ getDayOptions() {
385
+ const { locale } = this;
386
+ const days = [];
387
+ const minDay = this.getOptionEdge('min', 'date');
388
+ const maxDay = this.getOptionEdge('max', 'date');
389
+
390
+ for (let i = minDay; i <= maxDay; i += 1) {
391
+ days.push({
392
+ value: `${i}`,
393
+ label: `${i + locale.day}`,
394
+ });
395
+ }
398
396
 
399
- return hours;
400
- },
397
+ return days;
398
+ },
401
399
 
402
- getMinuteOptions() {
403
- const { locale } = this;
404
- const minutes = [];
405
- const minMinute = this.getOptionEdge('min', 'minute');
406
- const maxMinute = this.getOptionEdge('max', 'minute');
400
+ getHourOptions() {
401
+ const { locale } = this;
402
+ const hours = [];
403
+ const minHour = this.getOptionEdge('min', 'hour');
404
+ const maxHour = this.getOptionEdge('max', 'hour');
405
+
406
+ for (let i = minHour; i <= maxHour; i += 1) {
407
+ hours.push({
408
+ value: `${i}`,
409
+ label: `${i + locale.hour}`,
410
+ });
411
+ }
407
412
 
408
- for (let i = minMinute; i <= maxMinute; i += 1) {
409
- minutes.push({
410
- value: `${i}`,
411
- label: `${i + locale.minute}`,
412
- });
413
- }
413
+ return hours;
414
+ },
414
415
 
415
- return minutes;
416
- },
416
+ getMinuteOptions() {
417
+ const { locale } = this;
418
+ const minutes = [];
419
+ const minMinute = this.getOptionEdge('min', 'minute');
420
+ const maxMinute = this.getOptionEdge('max', 'minute');
421
+
422
+ for (let i = minMinute; i <= maxMinute; i += 1) {
423
+ minutes.push({
424
+ value: `${i}`,
425
+ label: `${i + locale.minute}`,
426
+ });
427
+ }
417
428
 
418
- getValueCols() {
419
- return {
420
- columns: this.getColumnOptions(),
421
- columnsValue: this.getColumnsValue(),
422
- };
423
- },
429
+ return minutes;
430
+ },
424
431
 
425
- getColumnsValue() {
426
- const { fullModes } = this;
427
- const date = this.getDate();
432
+ getValueCols() {
433
+ return {
434
+ columns: this.getColumnOptions(),
435
+ columnsValue: this.getColumnsValue(),
436
+ };
437
+ },
428
438
 
429
- const columnsValue = [];
439
+ getColumnsValue() {
440
+ const { fullModes } = this;
441
+ const date = this.getDate();
430
442
 
431
- fullModes?.forEach((mode) => {
432
- columnsValue.push(`${date[mode]()}`);
433
- });
443
+ const columnsValue = [];
434
444
 
435
- return columnsValue;
436
- },
445
+ fullModes?.forEach((mode) => {
446
+ columnsValue.push(`${date[mode]()}`);
447
+ });
437
448
 
438
- getNewDate(value, type) {
439
- let newValue = this.getDate();
440
-
441
- switch (type) {
442
- case ModeItem.YEAR:
443
- newValue = this.setYear(newValue, value);
444
- break;
445
- case ModeItem.MONTH:
446
- newValue = this.setMonth(newValue, value);
447
- break;
448
- case ModeItem.DATE:
449
- newValue = newValue.date(value);
450
- break;
451
- case ModeItem.HOUR:
452
- newValue = newValue.hour(value);
453
- break;
454
- case ModeItem.MINUTE:
455
- newValue = newValue.minute(value);
456
- break;
457
- case ModeItem.SECOND:
458
- newValue = newValue.second(value);
459
- break;
460
- default:
461
- break;
462
- }
463
-
464
- return this.clipDate(newValue);
465
- },
449
+ return columnsValue;
450
+ },
466
451
 
467
- onColumnChange(e) {
468
- const { value, column } = e;
469
- const { fullModes, format } = this;
452
+ getNewDate(value, type) {
453
+ let newValue = this.getDate();
454
+
455
+ switch (type) {
456
+ case ModeItem.YEAR:
457
+ newValue = this.setYear(newValue, value);
458
+ break;
459
+ case ModeItem.MONTH:
460
+ newValue = this.setMonth(newValue, value);
461
+ break;
462
+ case ModeItem.DATE:
463
+ newValue = newValue.date(value);
464
+ break;
465
+ case ModeItem.HOUR:
466
+ newValue = newValue.hour(value);
467
+ break;
468
+ case ModeItem.MINUTE:
469
+ newValue = newValue.minute(value);
470
+ break;
471
+ case ModeItem.SECOND:
472
+ newValue = newValue.second(value);
473
+ break;
474
+ default:
475
+ break;
476
+ }
470
477
 
471
- const columnValue = value?.[column];
472
- const columnType = fullModes?.[column];
478
+ return this.clipDate(newValue);
479
+ },
473
480
 
474
- const newValue = this.getNewDate(parseInt(columnValue, 10), columnType);
481
+ onColumnChange(e) {
482
+ const { value, column } = e;
483
+ const { fullModes, format } = this;
475
484
 
476
- this.date = newValue;
485
+ const columnValue = value?.[column];
486
+ const columnType = fullModes?.[column];
477
487
 
478
- const { columns, columnsValue } = this.getValueCols();
488
+ const newValue = this.getNewDate(parseInt(columnValue, 10), columnType);
479
489
 
480
- this.columns = columns;
481
- this.columnsValue = columnsValue;
490
+ this.date = newValue;
482
491
 
483
- const date = this.getDate();
484
- const pickValue = format ? date.format(format) : date.valueOf();
492
+ const { columns, columnsValue } = this.getValueCols();
485
493
 
486
- this.$emit('pick', { value: pickValue });
487
- },
494
+ this.columns = columns;
495
+ this.columnsValue = columnsValue;
488
496
 
489
- onConfirm() {
490
- const { format } = this;
491
- const date = this.getDate();
497
+ const date = this.getDate();
498
+ const pickValue = format ? date.format(format) : date.valueOf();
492
499
 
493
- const value = format ? date.format(format) : date.valueOf();
494
- this._trigger('change', { value });
495
- this.$emit('confirm', { value });
496
- this.resetColumns();
497
- },
500
+ this.$emit('pick', { value: pickValue });
501
+ },
498
502
 
499
- onCancel() {
500
- this.resetColumns();
501
- this.$emit('cancel');
502
- },
503
+ onConfirm() {
504
+ const { format } = this;
505
+ const date = this.getDate();
503
506
 
504
- onVisibleChange(e) {
505
- if (!e.visible) {
507
+ const value = format ? date.format(format) : date.valueOf();
508
+ this._trigger('change', { value });
509
+ this.$emit('confirm', { value });
506
510
  this.resetColumns();
507
- }
508
- },
511
+ },
509
512
 
510
- onClose(e) {
511
- const { trigger } = e;
513
+ onCancel() {
514
+ this.resetColumns();
515
+ this.$emit('cancel');
516
+ },
512
517
 
513
- this.$emit('close', { trigger });
514
- this.$emit('update:visible', false);
515
- },
518
+ onVisibleChange(e) {
519
+ if (!e.visible) {
520
+ this.resetColumns();
521
+ }
522
+ },
516
523
 
517
- resetColumns() {
518
- const parseDate = this.getParseDate();
524
+ onClose(e) {
525
+ const { trigger } = e;
519
526
 
520
- this.date = parseDate;
527
+ this.$emit('close', { trigger });
528
+ this.$emit('update:visible', false);
529
+ },
521
530
 
522
- const { columns, columnsValue } = this.getValueCols();
531
+ resetColumns() {
532
+ const parseDate = this.getParseDate();
523
533
 
524
- this.columns = columns;
525
- this.columnsValue = columnsValue;
526
- },
534
+ this.date = parseDate;
527
535
 
528
- // 将简写的 mode 转化成枚举值
529
- getFullModeArray(mode) {
530
- // 简易模式
531
- if (typeof mode === 'string' || mode instanceof String) {
532
- return this.getFullModeByModeString(mode, FULL_MODES);
533
- }
534
-
535
- // 高级模式
536
- if (Array.isArray(mode)) {
537
- if (mode?.length === 1) {
538
- return this.getFullModeByModeString(mode[0], FULL_MODES);
536
+ const { columns, columnsValue } = this.getValueCols();
537
+
538
+ this.columns = columns;
539
+ this.columnsValue = columnsValue;
540
+ },
541
+
542
+ // 将简写的 mode 转化成枚举值
543
+ getFullModeArray(mode) {
544
+ // 简易模式
545
+ if (typeof mode === 'string' || mode instanceof String) {
546
+ return this.getFullModeByModeString(mode, FULL_MODES);
539
547
  }
540
548
 
541
- if (mode?.length === 2) {
542
- const dateModes = this.getFullModeByModeString(mode[0], DATE_MODES);
543
- const timeModes = this.getFullModeByModeString(mode[1], TIME_MODES);
544
- return [...dateModes, ...timeModes];
549
+ // 高级模式
550
+ if (Array.isArray(mode)) {
551
+ if (mode?.length === 1) {
552
+ return this.getFullModeByModeString(mode[0], FULL_MODES);
553
+ }
554
+
555
+ if (mode?.length === 2) {
556
+ const dateModes = this.getFullModeByModeString(mode[0], DATE_MODES);
557
+ const timeModes = this.getFullModeByModeString(mode[1], TIME_MODES);
558
+ return [...dateModes, ...timeModes];
559
+ }
545
560
  }
546
- }
547
- },
561
+ },
548
562
 
549
- getFullModeByModeString(modeString, matchModes) {
550
- if (!modeString) {
551
- return [];
552
- }
563
+ getFullModeByModeString(modeString, matchModes) {
564
+ if (!modeString) {
565
+ return [];
566
+ }
553
567
 
554
- const endIndex = matchModes?.findIndex(mode => modeString === mode);
555
- return matchModes?.slice(0, endIndex + 1);
556
- },
568
+ const endIndex = matchModes?.findIndex(mode => modeString === mode);
569
+ return matchModes?.slice(0, endIndex + 1);
570
+ },
557
571
 
558
- // 仅展示时或者时分 需要单独特殊处理
559
- isTimeMode() {
560
- const { fullModes } = this;
561
- return fullModes[0] === ModeItem.HOUR;
572
+ // 仅展示时或者时分 需要单独特殊处理
573
+ isTimeMode() {
574
+ const { fullModes } = this;
575
+ return fullModes[0] === ModeItem.HOUR;
576
+ },
562
577
  },
563
- },
564
578
 
565
579
 
566
- });
580
+ }),
581
+ };
567
582
  </script>
568
583
  <style scoped src="./date-time-picker.css"></style>