xt-element-ui 2.1.5 → 2.1.7

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 (72) hide show
  1. package/docs/components/base/xt-badge.md +0 -2
  2. package/docs/components/base/xt-bar.md +5 -32
  3. package/docs/components/base/xt-button.md +0 -2
  4. package/docs/components/base/xt-card-item.md +0 -2
  5. package/docs/components/base/xt-card.md +17 -19
  6. package/docs/components/base/xt-chart.md +5 -31
  7. package/docs/components/base/xt-config-provider.md +0 -2
  8. package/docs/components/base/xt-date-picker.md +268 -180
  9. package/docs/components/base/xt-flex-box.md +25 -25
  10. package/docs/components/base/xt-form-schema.md +356 -0
  11. package/docs/components/base/xt-grid-box.md +4 -6
  12. package/docs/components/base/xt-icon.md +0 -2
  13. package/docs/components/base/xt-input.md +204 -44
  14. package/docs/components/base/xt-line.md +4 -30
  15. package/docs/components/base/xt-list.md +456 -458
  16. package/docs/components/base/xt-map-provider.md +0 -2
  17. package/docs/components/base/xt-map.md +0 -2
  18. package/docs/components/base/xt-multi.md +5 -44
  19. package/docs/components/base/xt-page.md +17 -6
  20. package/docs/components/base/xt-pie.md +5 -30
  21. package/docs/components/base/xt-progress.md +0 -2
  22. package/docs/components/base/xt-scroll-arrow.md +0 -2
  23. package/docs/components/base/xt-select-tree.md +0 -2
  24. package/docs/components/base/xt-step-price.md +0 -2
  25. package/docs/components/base/xt-table.md +2 -2
  26. package/docs/components/base/xt-tabs.md +0 -2
  27. package/docs/components/base/xt-text.md +1 -2
  28. package/docs/components/base/xt-time.md +0 -2
  29. package/docs/components/base/xt-transfer-tree.md +0 -2
  30. package/docs/components/base/xt-upload.md +11 -8
  31. package/docs/components/utils/config.md +285 -0
  32. package/docs/components/utils/format.md +445 -0
  33. package/package.json +5 -2
  34. package/src/components/xt-badge/style/index.scss +0 -22
  35. package/src/components/xt-chart/XtBar.vue +0 -3
  36. package/src/components/xt-date-picker/component/Picker.vue +196 -0
  37. package/src/components/xt-date-picker/component/RangeDate.vue +136 -0
  38. package/src/components/xt-date-picker/index.vue +164 -144
  39. package/src/components/xt-flex-box/index.vue +1 -1
  40. package/src/components/xt-form-schema/index.js +8 -0
  41. package/src/components/xt-form-schema/index.vue +328 -0
  42. package/src/components/xt-grid-item/index.vue +2 -2
  43. package/src/components/xt-input/index.vue +224 -28
  44. package/src/components/xt-input/style/index.scss +10 -0
  45. package/src/components/xt-layout/ExFieldset.vue +4 -4
  46. package/src/components/xt-list/index.js +7 -7
  47. package/src/components/xt-list/index.vue +885 -885
  48. package/src/components/xt-page/index.vue +148 -75
  49. package/src/components/xt-progress/style/index.scss +0 -14
  50. package/src/components/xt-tab-pane/index.js +10 -0
  51. package/src/components/{xt-tabs/TabPane.vue → xt-tab-pane/index.vue} +14 -1
  52. package/src/components/xt-table/XtTableCell.vue +2 -2
  53. package/src/components/xt-table/index.vue +5 -7
  54. package/src/components/xt-tabs/index.js +1 -3
  55. package/src/components/xt-tabs/index.vue +303 -44
  56. package/src/components/xt-tabs/style/index.scss +0 -40
  57. package/src/components/xt-text/style/index.scss +0 -15
  58. package/src/components/xt-transfer-tree/index.js +7 -7
  59. package/src/components/xt-transfer-tree/index.vue +493 -493
  60. package/src/components/xt-upload/index.vue +12 -6
  61. package/src/enhance/index.scss +13 -0
  62. package/src/index.js +7 -2
  63. package/src/styles/theme/colors.scss +0 -44
  64. package/src/styles/theme/dark-variables.scss +0 -29
  65. package/lib/demo.html +0 -10
  66. package/lib/index.common.js +0 -126851
  67. package/lib/index.css +0 -1
  68. package/lib/index.umd.js +0 -126861
  69. package/lib/index.umd.min.js +0 -1
  70. package/src/components/xt-date-picker/SearchDate.vue +0 -45
  71. package/src/components/xt-date-picker/quarter.vue +0 -154
  72. package/src/components/xt-table/index copy.vue +0 -663
@@ -0,0 +1,445 @@
1
+ ## 格式化工具函数
2
+
3
+ ## 概述
4
+
5
+ 提供常用的数据格式化工具函数,包括数字格式化、日期格式化、金额格式化等。
6
+
7
+ ## 数字格式化
8
+
9
+ ### formatNumber(value, options)
10
+
11
+ 通用数字格式化函数。
12
+
13
+ | 参数 | 类型 | 必填 | 说明 |
14
+ |------|------|------|------|
15
+ | `value` | Number / String | 是 | 要格式化的数字 |
16
+ | `options` | Object | 否 | 格式化选项 |
17
+
18
+ **options 参数**:
19
+
20
+ | 参数 | 类型 | 默认值 | 说明 |
21
+ |------|------|--------|------|
22
+ | `decimals` | Number | 2 | 小数位数 |
23
+ | `thousand` | Boolean | true | 是否千分位分隔 |
24
+ | `prefix` | String | '' | 前缀 |
25
+ | `suffix` | String | '' | 后缀 |
26
+ | `showSign` | Boolean | false | 正数是否显示正号 |
27
+
28
+ ```vue
29
+ <template>
30
+ <div>
31
+ <XtText>{{ formatNumber(12345.6789) }}</XtText>
32
+ <XtText>{{ formatNumber(12345.6789, { decimals: 0 }) }}</XtText>
33
+ <XtText>{{ formatNumber(0.1234, { suffix: '%', decimals: 1 }) }}</XtText>
34
+ </div>
35
+ </template>
36
+
37
+ <script>
38
+ import { formatNumber } from 'xt-element-ui'
39
+
40
+ export default {
41
+ methods: {
42
+ formatNumber
43
+ }
44
+ }
45
+ </script>
46
+ ```
47
+
48
+ ### formatThousand(value, decimals)
49
+
50
+ 千分位格式化,简化版的 formatNumber。
51
+
52
+ | 参数 | 类型 | 必填 | 说明 |
53
+ |------|------|------|------|
54
+ | `value` | Number / String | 是 | 要格式化的数字 |
55
+ | `decimals` | Number | 否 | 小数位数,默认 2 |
56
+
57
+ ```vue
58
+ <template>
59
+ <div>
60
+ <XtText>{{ formatThousand(1234567.89) }}</XtText>
61
+ <XtText>{{ formatThousand(1234567.89, 0) }}</XtText>
62
+ </div>
63
+ </template>
64
+
65
+ <script>
66
+ import { formatThousand } from 'xt-element-ui'
67
+
68
+ export default {
69
+ methods: {
70
+ formatThousand
71
+ }
72
+ }
73
+ </script>
74
+ ```
75
+
76
+ ### formatPercent(value, decimals)
77
+
78
+ 百分比格式化,自动将小数转换为百分比。
79
+
80
+ | 参数 | 类型 | 必填 | 说明 |
81
+ |------|------|------|------|
82
+ | `value` | Number / String | 是 | 要格式化的数字(小数形式) |
83
+ | `decimals` | Number | 否 | 小数位数,默认 2 |
84
+
85
+ ```vue
86
+ <template>
87
+ <div>
88
+ <XtText>{{ formatPercent(0.1234) }}</XtText>
89
+ <XtText>{{ formatPercent(0.5, 1) }}</XtText>
90
+ </div>
91
+ </template>
92
+
93
+ <script>
94
+ import { formatPercent } from 'xt-element-ui'
95
+
96
+ export default {
97
+ methods: {
98
+ formatPercent
99
+ }
100
+ }
101
+ </script>
102
+ ```
103
+
104
+ ## 日期格式化
105
+
106
+ ### formatDate(date, format)
107
+
108
+ 日期格式化函数,支持多种格式。
109
+
110
+ | 参数 | 类型 | 必填 | 说明 |
111
+ |------|------|------|------|
112
+ | `date` | Date / Number / String | 是 | 日期对象、时间戳、日期字符串 |
113
+ | `format` | String | 否 | 格式字符串,默认 `yyyy-MM-dd` |
114
+
115
+ **格式占位符**:
116
+
117
+ | 占位符 | 说明 | 示例 |
118
+ |--------|------|------|
119
+ | `yyyy` | 4位年份 | 2026 |
120
+ | `MM` | 2位月份 | 07 |
121
+ | `M` | 1位月份 | 7 |
122
+ | `dd` | 2位日期 | 08 |
123
+ | `d` | 1位日期 | 8 |
124
+ | `HH` | 24小时制(2位) | 14 |
125
+ | `H` | 24小时制(1位) | 14 |
126
+ | `hh` | 12小时制(2位) | 02 |
127
+ | `h` | 12小时制(1位) | 2 |
128
+ | `mm` | 分钟(2位) | 30 |
129
+ | `m` | 分钟(1位) | 30 |
130
+ | `ss` | 秒(2位) | 45 |
131
+ | `s` | 秒(1位) | 45 |
132
+ | `w` | 星期几(简写) | 一 |
133
+ | `W` | 星期几(完整) | 星期一 |
134
+
135
+ ```vue
136
+ <template>
137
+ <div>
138
+ <XtText>{{ formatDate(new Date()) }}</XtText>
139
+ <XtText>{{ formatDate(new Date(), 'yyyy年MM月dd日') }}</XtText>
140
+ <XtText>{{ formatDate(new Date(), 'MM-dd HH:mm') }}</XtText>
141
+ <XtText>{{ formatDate(new Date(), 'yyyy-MM-dd W') }}</XtText>
142
+ </div>
143
+ </template>
144
+
145
+ <script>
146
+ import { formatDate } from 'xt-element-ui'
147
+
148
+ export default {
149
+ methods: {
150
+ formatDate
151
+ }
152
+ }
153
+ </script>
154
+ ```
155
+
156
+ ### formatDateTime(date, format)
157
+
158
+ 日期时间格式化,默认格式为 `yyyy-MM-dd HH:mm:ss`。
159
+
160
+ ```vue
161
+ <template>
162
+ <div>
163
+ <XtText>{{ formatDateTime(new Date()) }}</XtText>
164
+ <XtText>{{ formatDateTime(new Date(), 'yyyy/MM/dd HH:mm') }}</XtText>
165
+ </div>
166
+ </template>
167
+
168
+ <script>
169
+ import { formatDateTime } from 'xt-element-ui'
170
+
171
+ export default {
172
+ methods: {
173
+ formatDateTime
174
+ }
175
+ }
176
+ </script>
177
+ ```
178
+
179
+ ### formatTime(date, format)
180
+
181
+ 时间格式化,默认格式为 `HH:mm:ss`。
182
+
183
+ ```vue
184
+ <template>
185
+ <div>
186
+ <XtText>{{ formatTime(new Date()) }}</XtText>
187
+ <XtText>{{ formatTime(new Date(), 'HH:mm') }}</XtText>
188
+ </div>
189
+ </template>
190
+
191
+ <script>
192
+ import { formatTime } from 'xt-element-ui'
193
+
194
+ export default {
195
+ methods: {
196
+ formatTime
197
+ }
198
+ }
199
+ </script>
200
+ ```
201
+
202
+ ### formatRelativeTime(date)
203
+
204
+ 相对时间格式化,返回"几分钟前"、"几小时前"等格式。
205
+
206
+ ```vue
207
+ <template>
208
+ <div>
209
+ <XtText>{{ formatRelativeTime(Date.now() - 3600000) }}</XtText>
210
+ <XtText>{{ formatRelativeTime(Date.now() - 86400000) }}</XtText>
211
+ <XtText>{{ formatRelativeTime(Date.now() - 604800000) }}</XtText>
212
+ </div>
213
+ </template>
214
+
215
+ <script>
216
+ import { formatRelativeTime } from 'xt-element-ui'
217
+
218
+ export default {
219
+ methods: {
220
+ formatRelativeTime
221
+ }
222
+ }
223
+ </script>
224
+ ```
225
+
226
+ **相对时间对照表**:
227
+
228
+ | 时间范围 | 显示格式 |
229
+ |----------|----------|
230
+ | < 1分钟 | 刚刚 |
231
+ | < 1小时 | X分钟前 |
232
+ | < 1天 | X小时前 |
233
+ | < 1周 | X天前 |
234
+ | < 1月 | X周前 |
235
+ | < 1年 | X个月前 |
236
+ | >= 1年 | X年前 |
237
+
238
+ ## 金额格式化
239
+
240
+ ### formatMoney(value, options)
241
+
242
+ 通用金额格式化函数。
243
+
244
+ | 参数 | 类型 | 必填 | 说明 |
245
+ |------|------|------|------|
246
+ | `value` | Number / String | 是 | 金额数字 |
247
+ | `options` | Object | 否 | 格式化选项 |
248
+
249
+ **options 参数**:
250
+
251
+ | 参数 | 类型 | 默认值 | 说明 |
252
+ |------|------|--------|------|
253
+ | `currency` | String | 'CNY' | 货币类型 |
254
+ | `decimals` | Number | 2 | 小数位数 |
255
+ | `prefix` | String | '' | 前缀 |
256
+ | `suffix` | String | '' | 后缀 |
257
+ | `showSign` | Boolean | false | 正数是否显示正号 |
258
+
259
+ **支持的货币类型**:
260
+
261
+ | 货币 | 符号 | 说明 |
262
+ |------|------|------|
263
+ | CNY | ¥ | 人民币 |
264
+ | USD | $ | 美元 |
265
+ | EUR | € | 欧元 |
266
+ | JPY | ¥ | 日元 |
267
+ | GBP | £ | 英镑 |
268
+ | AUD | A$ | 澳元 |
269
+ | CAD | C$ | 加元 |
270
+
271
+ ```vue
272
+ <template>
273
+ <div>
274
+ <XtText>{{ formatMoney(12345.67) }}</XtText>
275
+ <XtText>{{ formatMoney(12345.67, { currency: 'USD' }) }}</XtText>
276
+ <XtText>{{ formatMoney(12345.67, { currency: 'EUR', decimals: 0 }) }}</XtText>
277
+ </div>
278
+ </template>
279
+
280
+ <script>
281
+ import { formatMoney } from 'xt-element-ui'
282
+
283
+ export default {
284
+ methods: {
285
+ formatMoney
286
+ }
287
+ }
288
+ </script>
289
+ ```
290
+
291
+ ### formatCNY(value, decimals)
292
+
293
+ 人民币格式化,简化版的 formatMoney。
294
+
295
+ ```vue
296
+ <template>
297
+ <div>
298
+ <XtText>{{ formatCNY(12345.67) }}</XtText>
299
+ <XtText>{{ formatCNY(12345.67, 0) }}</XtText>
300
+ </div>
301
+ </template>
302
+
303
+ <script>
304
+ import { formatCNY } from 'xt-element-ui'
305
+
306
+ export default {
307
+ methods: {
308
+ formatCNY
309
+ }
310
+ }
311
+ </script>
312
+ ```
313
+
314
+ ### formatUSD(value, decimals)
315
+
316
+ 美元格式化,简化版的 formatMoney。
317
+
318
+ ```vue
319
+ <template>
320
+ <div>
321
+ <XtText>{{ formatUSD(12345.67) }}</XtText>
322
+ <XtText>{{ formatUSD(12345.67, 0) }}</XtText>
323
+ </div>
324
+ </template>
325
+
326
+ <script>
327
+ import { formatUSD } from 'xt-element-ui'
328
+
329
+ export default {
330
+ methods: {
331
+ formatUSD
332
+ }
333
+ }
334
+ </script>
335
+ ```
336
+
337
+ ## 文件大小格式化
338
+
339
+ ### formatFileSize(bytes)
340
+
341
+ 文件大小格式化,自动转换单位。
342
+
343
+ | 参数 | 类型 | 必填 | 说明 |
344
+ |------|------|------|------|
345
+ | `bytes` | Number / String | 是 | 文件字节数 |
346
+
347
+ ```vue
348
+ <template>
349
+ <div>
350
+ <XtText>{{ formatFileSize(1024) }}</XtText>
351
+ <XtText>{{ formatFileSize(1024 * 1024) }}</XtText>
352
+ <XtText>{{ formatFileSize(1024 * 1024 * 1024) }}</XtText>
353
+ </div>
354
+ </template>
355
+
356
+ <script>
357
+ import { formatFileSize } from 'xt-element-ui'
358
+
359
+ export default {
360
+ methods: {
361
+ formatFileSize
362
+ }
363
+ }
364
+ </script>
365
+ ```
366
+
367
+ **单位对照表**:
368
+
369
+ | 范围 | 单位 |
370
+ |------|------|
371
+ | < 1KB | B |
372
+ | < 1MB | KB |
373
+ | < 1GB | MB |
374
+ | < 1TB | GB |
375
+ | >= 1TB | TB |
376
+
377
+ ## 综合示例
378
+
379
+ ```vue
380
+ <template>
381
+ <XtCard>
382
+ <XtCardItem title="数字格式化">
383
+ <XtFlexBox>
384
+ <XtText>千分位:{{ formatThousand(1234567.89) }}</XtText>
385
+ <XtText>百分比:{{ formatPercent(0.75) }}</XtText>
386
+ </XtFlexBox>
387
+ </XtCardItem>
388
+
389
+ <XtCardItem title="日期格式化">
390
+ <XtFlexBox>
391
+ <XtText>日期:{{ formatDate(new Date()) }}</XtText>
392
+ <XtText>时间:{{ formatTime(new Date()) }}</XtText>
393
+ <XtText>相对时间:{{ formatRelativeTime(Date.now() - 3600000) }}</XtText>
394
+ </XtFlexBox>
395
+ </XtCardItem>
396
+
397
+ <XtCardItem title="金额格式化">
398
+ <XtFlexBox>
399
+ <XtText>人民币:{{ formatCNY(12345.67) }}</XtText>
400
+ <XtText>美元:{{ formatUSD(12345.67) }}</XtText>
401
+ </XtFlexBox>
402
+ </XtCardItem>
403
+
404
+ <XtCardItem title="文件大小">
405
+ <XtFlexBox>
406
+ <XtText>{{ formatFileSize(524288) }}</XtText>
407
+ <XtText>{{ formatFileSize(1073741824) }}</XtText>
408
+ </XtFlexBox>
409
+ </XtCardItem>
410
+ </XtCard>
411
+ </template>
412
+
413
+ <script>
414
+ import {
415
+ formatThousand,
416
+ formatPercent,
417
+ formatDate,
418
+ formatTime,
419
+ formatRelativeTime,
420
+ formatCNY,
421
+ formatUSD,
422
+ formatFileSize
423
+ } from 'xt-element-ui'
424
+
425
+ export default {
426
+ methods: {
427
+ formatThousand,
428
+ formatPercent,
429
+ formatDate,
430
+ formatTime,
431
+ formatRelativeTime,
432
+ formatCNY,
433
+ formatUSD,
434
+ formatFileSize
435
+ }
436
+ }
437
+ </script>
438
+ ```
439
+
440
+ ## 注意事项
441
+
442
+ 1. 所有格式化函数对 `null`、`undefined`、空字符串返回空字符串
443
+ 2. 对无法转换为数字的值,返回原值的字符串形式
444
+ 3. 时间戳支持 10 位(秒)和 13 位(毫秒)两种格式
445
+ 4. 日期字符串支持 `yyyy-MM-dd`、`yyyy/MM/dd` 等常见格式
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xt-element-ui",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "基于 Vue 2.7 + ElementUI 的企业级组件库,提供丰富的自定义组件和扩展组件",
5
5
  "main": "lib/index.common.js",
6
6
  "module": "lib/index.esm.js",
@@ -11,13 +11,16 @@
11
11
  "docs:build": "vuepress build docs",
12
12
  "dev": "vue-cli-service serve",
13
13
  "lib": "vue-cli-service build --target lib --name index --dest lib src/index.js",
14
- "prepublishOnly": "npm run lib"
14
+ "prepublishOnly": "npm run lib",
15
+ "postinstall": "patch-package"
15
16
  },
16
17
  "peerDependencies": {
17
18
  "vue": "^2.6.10"
18
19
  },
19
20
  "devDependencies": {
20
21
  "@vue/cli-service": "~4.5.19",
22
+ "null-loader": "^4.0.1",
23
+ "patch-package": "^8.0.1",
21
24
  "sass": "^1.56.0",
22
25
  "sass-loader": "^10.5.2",
23
26
  "vuepress": "^1.9.10",
@@ -64,25 +64,3 @@
64
64
  .xt-badge--hidden {
65
65
  display: none;
66
66
  }
67
-
68
- [data-theme='dark'], html.dark {
69
- .xt-badge--primary .xt-badge__badge {
70
- background: $xt-dark-color-primary;
71
- }
72
-
73
- .xt-badge--success .xt-badge__badge {
74
- background: $xt-dark-color-success;
75
- }
76
-
77
- .xt-badge--warning .xt-badge__badge {
78
- background: $xt-dark-color-warning;
79
- }
80
-
81
- .xt-badge--danger .xt-badge__badge {
82
- background: $xt-dark-color-danger;
83
- }
84
-
85
- .xt-badge--info .xt-badge__badge {
86
- background: $xt-dark-color-info;
87
- }
88
- }
@@ -161,9 +161,6 @@ export default {
161
161
  },
162
162
  min: 0,
163
163
  splitNumber: _self.splitNumber,
164
- max: function(value) {
165
- return Math.ceil(value.max / _self.splitNumber) * _self.splitNumber;
166
- },
167
164
  scale: true,
168
165
  axisLabel: {
169
166
  margin: 2,
@@ -0,0 +1,196 @@
1
+ <template>
2
+ <div class="base-date-root">
3
+ <el-date-picker
4
+ v-if="type !== 'quarter'"
5
+ v-model="innerValue"
6
+ v-bind="$attrs"
7
+ v-on="$listeners"
8
+ :type="pickerType"
9
+ :value-format="valueFormat"
10
+ :disabled="disabled"
11
+ :placeholder="placeholder"
12
+ popper-append-to-body
13
+ popper-class="base-date-popper"
14
+ />
15
+
16
+ <el-popover
17
+ v-else
18
+ v-model="quarterPopVisible"
19
+ trigger="manual"
20
+ placement="bottom-start"
21
+ width="240"
22
+ >
23
+ <div class="quarter-panel">
24
+ <div class="quarter-header">
25
+ <el-button icon="el-icon-d-arrow-left" @click="year--"></el-button>
26
+ <span>{{ year }} 年</span>
27
+ <el-button icon="el-icon-d-arrow-right" @click="year++"></el-button>
28
+ </div>
29
+ <div class="quarter-list">
30
+ <div
31
+ v-for="q in 4"
32
+ :key="q"
33
+ class="quarter-item"
34
+ :class="{ active: quarterNum === q }"
35
+ @click="selectQuarter(q)"
36
+ >
37
+ Q{{ q }}
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ <el-input
43
+ slot="reference"
44
+ ref="quarterInput"
45
+ v-model="quarterShowText"
46
+ size="small"
47
+ readonly
48
+ :placeholder="placeholder"
49
+ :disabled="disabled"
50
+ clearable
51
+ @clear="handleClearQuarter"
52
+ >
53
+ <i slot="affix" class="el-icon-date"></i>
54
+ </el-input>
55
+ </el-popover>
56
+ </div>
57
+ </template>
58
+
59
+ <script>
60
+ export default {
61
+ name: 'BaseDatePicker',
62
+ inheritAttrs: false,
63
+ props: {
64
+ value: {
65
+ type: [String, null],
66
+ default: null
67
+ },
68
+ type: {
69
+ type: String,
70
+ default: 'date',
71
+ validator: val => ['date', 'month', 'year', 'quarter', 'week'].includes(val)
72
+ },
73
+ disabled: {
74
+ type: Boolean,
75
+ default: false
76
+ },
77
+ placeholder: String,
78
+ valueFormat: String
79
+ },
80
+ data() {
81
+ return {
82
+ quarterPopVisible: false,
83
+ year: new Date().getFullYear(),
84
+ quarterNum: null
85
+ }
86
+ },
87
+ computed: {
88
+ pickerType() {
89
+ return this.type === 'quarter' ? null : this.type
90
+ },
91
+ placeholder() {
92
+ if (this.$props.placeholder) return this.$props.placeholder
93
+ const map = {
94
+ date: '请选择日期',
95
+ month: '请选择月份',
96
+ year: '请选择年份',
97
+ quarter: '请选择季度',
98
+ week: '请选择周'
99
+ }
100
+ return map[this.type] || '请选择日期'
101
+ },
102
+ valueFormat() {
103
+ if (this.$props.valueFormat) return this.$props.valueFormat
104
+ const map = {
105
+ date: 'yyyy-MM-dd',
106
+ month: 'yyyy-MM',
107
+ year: 'yyyy',
108
+ quarter: 'yyyy-Qq',
109
+ week: 'yyyy-WW'
110
+ }
111
+ return map[this.type] || 'yyyy-MM-dd'
112
+ },
113
+ innerValue: {
114
+ get() { return this.value },
115
+ set(val) { this.$emit('input', val) }
116
+ },
117
+ quarterShowText() {
118
+ if (!this.value) return ''
119
+ return `${this.year}-Q${this.quarterNum}`
120
+ }
121
+ },
122
+ watch: {
123
+ value: {
124
+ handler(val) {
125
+ if (this.type !== 'quarter' || !val) {
126
+ this.quarterNum = null
127
+ return
128
+ }
129
+ const [y, q] = val.split('-Q')
130
+ this.year = Number(y)
131
+ this.quarterNum = Number(q)
132
+ },
133
+ immediate: true
134
+ }
135
+ },
136
+ methods: {
137
+ selectQuarter(q) {
138
+ this.quarterNum = q
139
+ const val = `${this.year}-Q${q}`
140
+ this.$emit('input', val)
141
+ this.quarterPopVisible = false
142
+ },
143
+ handleClearQuarter() {
144
+ this.quarterNum = null
145
+ this.$emit('input', null)
146
+ }
147
+ },
148
+ mounted() {
149
+ if (this.type === 'quarter' && this.$refs.quarterInput) {
150
+ this.$refs.quarterInput.$el.addEventListener('click', () => {
151
+ if (!this.disabled) this.quarterPopVisible = true
152
+ })
153
+ }
154
+ }
155
+ }
156
+ </script>
157
+
158
+ <style scoped>
159
+ .base-date-root {
160
+ }
161
+
162
+ .quarter-panel {
163
+ padding: 10px;
164
+ }
165
+
166
+ .quarter-header {
167
+ display: flex;
168
+ align-items: center;
169
+ justify-content: space-between;
170
+ margin-bottom: 10px;
171
+ }
172
+
173
+ .quarter-list {
174
+ display: grid;
175
+ grid-template-columns: repeat(2, 1fr);
176
+ gap: 8px;
177
+ }
178
+
179
+ .quarter-item {
180
+ text-align: center;
181
+ padding: 8px 0;
182
+ border: 1px solid #e4e7ed;
183
+ border-radius: 4px;
184
+ cursor: pointer;
185
+ }
186
+
187
+ .quarter-item.active {
188
+ background: #409eff;
189
+ color: #fff;
190
+ border-color: #409eff;
191
+ }
192
+
193
+ ::v-deep .base-date-popper {
194
+ border-radius: 4px;
195
+ }
196
+ </style>