@hbdlzy/ui-core 0.1.1 → 0.1.2
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.
- package/README.md +37 -2
- package/components.manifest.json +195 -163
- package/dist/index.cjs +1 -1
- package/dist/index.js +1877 -13
- package/dist/style.css +1 -1
- package/package.json +2 -1
- package/src/components/OutlinedCascader/OutlinedCascader.types.ts +28 -0
- package/src/components/OutlinedCascader/OutlinedCascader.vue +250 -0
- package/src/components/OutlinedCascader/README.md +91 -0
- package/src/components/OutlinedCascader/index.ts +10 -0
- package/src/components/OutlinedDatePicker/OutlinedDatePicker.types.ts +40 -0
- package/src/components/OutlinedDatePicker/OutlinedDatePicker.vue +365 -0
- package/src/components/OutlinedDatePicker/README.md +137 -0
- package/src/components/OutlinedDatePicker/index.ts +11 -0
- package/src/components/OutlinedDateTimePicker/OutlinedDateTimePicker.types.ts +34 -0
- package/src/components/OutlinedDateTimePicker/OutlinedDateTimePicker.vue +421 -0
- package/src/components/OutlinedDateTimePicker/README.md +88 -0
- package/src/components/OutlinedDateTimePicker/index.ts +11 -0
- package/src/components/OutlinedInput/OutlinedInput.types.ts +32 -0
- package/src/components/OutlinedInput/OutlinedInput.vue +307 -0
- package/src/components/OutlinedInput/README.md +154 -0
- package/src/components/OutlinedInput/index.ts +10 -0
- package/src/components/OutlinedSelect/OutlinedSelect.types.ts +48 -0
- package/src/components/OutlinedSelect/OutlinedSelect.vue +359 -0
- package/src/components/OutlinedSelect/README.md +166 -0
- package/src/components/OutlinedSelect/index.ts +12 -0
- package/src/components/OutlinedTimePicker/OutlinedTimePicker.types.ts +36 -0
- package/src/components/OutlinedTimePicker/OutlinedTimePicker.vue +303 -0
- package/src/components/OutlinedTimePicker/README.md +93 -0
- package/src/components/OutlinedTimePicker/index.ts +10 -0
- package/src/components/OutlinedTreeSelect/OutlinedTreeSelect.types.ts +56 -0
- package/src/components/OutlinedTreeSelect/OutlinedTreeSelect.vue +354 -0
- package/src/components/OutlinedTreeSelect/README.md +107 -0
- package/src/components/OutlinedTreeSelect/index.ts +12 -0
- package/src/index.ts +14 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="outlined-date-picker"
|
|
4
|
+
:class="[containerClasses, rootClass]"
|
|
5
|
+
:style="[containerStyle, rootStyle]"
|
|
6
|
+
>
|
|
7
|
+
<el-date-picker
|
|
8
|
+
ref="pickerRef"
|
|
9
|
+
v-bind="pickerAttrs"
|
|
10
|
+
class="outlined-date-picker__control"
|
|
11
|
+
:model-value="pickerValue"
|
|
12
|
+
:type="typeDate"
|
|
13
|
+
:format="format"
|
|
14
|
+
:value-format="resolvedValueFormat"
|
|
15
|
+
:placeholder="placeholder"
|
|
16
|
+
:disabled="disabled"
|
|
17
|
+
:style="pickerStyle"
|
|
18
|
+
@update:model-value="handleModelValueUpdate"
|
|
19
|
+
@focus="handleFocus"
|
|
20
|
+
@blur="handleBlur"
|
|
21
|
+
@change="handleChange"
|
|
22
|
+
@visible-change="handleVisibleChange"
|
|
23
|
+
/>
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
v-if="floatingLabel"
|
|
27
|
+
class="outlined-date-picker__label"
|
|
28
|
+
:class="labelClasses"
|
|
29
|
+
>
|
|
30
|
+
{{ floatingLabel }}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup lang="ts">
|
|
36
|
+
import { computed, ref, useAttrs, watch } from 'vue'
|
|
37
|
+
import type {
|
|
38
|
+
OutlinedDatePickerCssValue,
|
|
39
|
+
OutlinedDatePickerDisabledDate,
|
|
40
|
+
OutlinedDatePickerExpose,
|
|
41
|
+
OutlinedDatePickerProps,
|
|
42
|
+
OutlinedDatePickerValue
|
|
43
|
+
} from './OutlinedDatePicker.types'
|
|
44
|
+
|
|
45
|
+
defineOptions({
|
|
46
|
+
name: 'OutlinedDatePicker',
|
|
47
|
+
inheritAttrs: false
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const props = withDefaults(defineProps<OutlinedDatePickerProps>(), {
|
|
51
|
+
value: '',
|
|
52
|
+
placeholder: '',
|
|
53
|
+
label: '',
|
|
54
|
+
disabled: false,
|
|
55
|
+
timeValue: false,
|
|
56
|
+
typeDate: 'date',
|
|
57
|
+
format: 'YYYY-MM-DD',
|
|
58
|
+
valueFormat: '',
|
|
59
|
+
showPassword: false,
|
|
60
|
+
multiple: false,
|
|
61
|
+
inputHeight: 40,
|
|
62
|
+
isBorder: false,
|
|
63
|
+
disabledDate: undefined,
|
|
64
|
+
marginBottom: 20,
|
|
65
|
+
paddingTop: 20
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const emit = defineEmits<{
|
|
69
|
+
(event: 'input', value: OutlinedDatePickerValue | ''): void
|
|
70
|
+
(event: 'update:value', value: OutlinedDatePickerValue | ''): void
|
|
71
|
+
(event: 'change', value: OutlinedDatePickerValue | ''): void
|
|
72
|
+
(event: 'focus', value: FocusEvent): void
|
|
73
|
+
(event: 'blur', value: FocusEvent): void
|
|
74
|
+
(event: 'visible-change', value: boolean): void
|
|
75
|
+
}>()
|
|
76
|
+
|
|
77
|
+
const attrs = useAttrs()
|
|
78
|
+
const pickerRef = ref<any>(null)
|
|
79
|
+
const pickerValue = ref<OutlinedDatePickerValue | ''>(props.value ?? '')
|
|
80
|
+
const focused = ref(false)
|
|
81
|
+
const blurred = ref(false)
|
|
82
|
+
const visible = ref(false)
|
|
83
|
+
|
|
84
|
+
watch(
|
|
85
|
+
() => props.value,
|
|
86
|
+
(value) => {
|
|
87
|
+
pickerValue.value = value ?? ''
|
|
88
|
+
},
|
|
89
|
+
{ immediate: true }
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const rootClass = computed(() => attrs.class)
|
|
93
|
+
const rootStyle = computed(() => attrs.style)
|
|
94
|
+
|
|
95
|
+
const resolvedValueFormat = computed(() => props.valueFormat || props.format)
|
|
96
|
+
|
|
97
|
+
const resolvedDisabledDate = computed(() => createDisabledDateHandler(props.disabledDate))
|
|
98
|
+
|
|
99
|
+
const resolvedDefaultTime = computed(() => {
|
|
100
|
+
if (attrs.defaultTime !== undefined) {
|
|
101
|
+
return attrs.defaultTime
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if ((attrs as Record<string, unknown>)['default-time'] !== undefined) {
|
|
105
|
+
return (attrs as Record<string, unknown>)['default-time']
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return props.timeValue ? new Date().setHours(0, 0, 0, 0) : new Date()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
const resolvedDisabledHours = computed(() => {
|
|
112
|
+
if (attrs.disabledHours !== undefined) {
|
|
113
|
+
return attrs.disabledHours
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if ((attrs as Record<string, unknown>)['disabled-hours'] !== undefined) {
|
|
117
|
+
return (attrs as Record<string, unknown>)['disabled-hours']
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!shouldLimitCurrentTime()) {
|
|
121
|
+
return undefined
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return () => {
|
|
125
|
+
const hours = new Date().getHours()
|
|
126
|
+
return Array.from({ length: hours }, (_, index) => index)
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const resolvedDisabledMinutes = computed(() => {
|
|
131
|
+
if (attrs.disabledMinutes !== undefined) {
|
|
132
|
+
return attrs.disabledMinutes
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if ((attrs as Record<string, unknown>)['disabled-minutes'] !== undefined) {
|
|
136
|
+
return (attrs as Record<string, unknown>)['disabled-minutes']
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!shouldLimitCurrentTime()) {
|
|
140
|
+
return undefined
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return () => {
|
|
144
|
+
const minutes = new Date().getMinutes()
|
|
145
|
+
return Array.from({ length: minutes }, (_, index) => index)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
const pickerAttrs = computed(() => {
|
|
150
|
+
const { class: _class, style: _style, ...rest } = attrs
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
...rest,
|
|
154
|
+
defaultTime: resolvedDefaultTime.value,
|
|
155
|
+
disabledDate: resolvedDisabledDate.value,
|
|
156
|
+
disabledHours: resolvedDisabledHours.value,
|
|
157
|
+
disabledMinutes: resolvedDisabledMinutes.value
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const containerClasses = computed(() => ({
|
|
162
|
+
'outlined-date-picker--bordered': props.isBorder
|
|
163
|
+
}))
|
|
164
|
+
|
|
165
|
+
const containerStyle = computed(() => ({
|
|
166
|
+
marginBottom: toCssValue(props.marginBottom),
|
|
167
|
+
paddingTop: toCssValue(props.paddingTop)
|
|
168
|
+
}))
|
|
169
|
+
|
|
170
|
+
const pickerStyle = computed(() => ({
|
|
171
|
+
height: `${props.inputHeight}px`
|
|
172
|
+
}))
|
|
173
|
+
|
|
174
|
+
const floatingLabel = computed(() => props.label || props.placeholder || '')
|
|
175
|
+
|
|
176
|
+
const hasContent = computed(() => hasFilledValue(pickerValue.value))
|
|
177
|
+
|
|
178
|
+
const labelClasses = computed(() => ({
|
|
179
|
+
'outlined-date-picker__label--floating': focused.value || hasContent.value,
|
|
180
|
+
'outlined-date-picker__label--placeholder': !focused.value && !hasContent.value,
|
|
181
|
+
'outlined-date-picker__label--filled': hasContent.value && !focused.value
|
|
182
|
+
}))
|
|
183
|
+
|
|
184
|
+
function handleModelValueUpdate(value: OutlinedDatePickerValue) {
|
|
185
|
+
const normalizedValue = normalizeValue(value)
|
|
186
|
+
pickerValue.value = normalizedValue
|
|
187
|
+
emitModelValue(normalizedValue)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function handleChange(value: OutlinedDatePickerValue) {
|
|
191
|
+
const normalizedValue = normalizeValue(value)
|
|
192
|
+
pickerValue.value = normalizedValue
|
|
193
|
+
emit('change', normalizedValue)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function handleFocus(event: FocusEvent) {
|
|
197
|
+
blurred.value = false
|
|
198
|
+
focused.value = true
|
|
199
|
+
emit('focus', event)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function handleBlur(event: FocusEvent) {
|
|
203
|
+
blurred.value = true
|
|
204
|
+
|
|
205
|
+
if (!visible.value) {
|
|
206
|
+
focused.value = false
|
|
207
|
+
emitModelValue(pickerValue.value)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
emit('blur', event)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function handleVisibleChange(nextVisible: boolean) {
|
|
214
|
+
visible.value = nextVisible
|
|
215
|
+
|
|
216
|
+
if (!nextVisible && blurred.value) {
|
|
217
|
+
focused.value = false
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
emit('visible-change', nextVisible)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function emitModelValue(value: OutlinedDatePickerValue | '') {
|
|
224
|
+
emit('input', value)
|
|
225
|
+
emit('update:value', value)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function normalizeValue(value: OutlinedDatePickerValue | undefined) {
|
|
229
|
+
return value ?? ''
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function createDisabledDateHandler(disabledDate: OutlinedDatePickerDisabledDate | undefined) {
|
|
233
|
+
if (!disabledDate) {
|
|
234
|
+
return undefined
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (typeof disabledDate === 'function') {
|
|
238
|
+
return disabledDate
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const boundary = normalizeBoundary(disabledDate)
|
|
242
|
+
|
|
243
|
+
return (value: Date) => value.getTime() < boundary - 86400000
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function normalizeBoundary(value: Exclude<OutlinedDatePickerDisabledDate, ((date: Date) => boolean)>) {
|
|
247
|
+
if (value === 'nowDate') {
|
|
248
|
+
return Date.now()
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (value instanceof Date) {
|
|
252
|
+
return value.getTime()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (typeof value === 'number') {
|
|
256
|
+
return value
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return new Date(value).getTime()
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function shouldLimitCurrentTime() {
|
|
263
|
+
return Boolean(props.disabledDate) && props.typeDate.toLowerCase().includes('time')
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function hasFilledValue(value: unknown) {
|
|
267
|
+
if (Array.isArray(value)) {
|
|
268
|
+
return value.length > 0
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return value !== undefined && value !== null && String(value) !== ''
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function toCssValue(value: OutlinedDatePickerCssValue | undefined) {
|
|
275
|
+
if (typeof value === 'number') {
|
|
276
|
+
return `${value}px`
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return value
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
defineExpose<OutlinedDatePickerExpose>({
|
|
283
|
+
focus: () => {
|
|
284
|
+
pickerRef.value?.focus?.()
|
|
285
|
+
},
|
|
286
|
+
blur: () => {
|
|
287
|
+
pickerRef.value?.blur?.()
|
|
288
|
+
},
|
|
289
|
+
handleOpen: () => {
|
|
290
|
+
pickerRef.value?.handleOpen?.()
|
|
291
|
+
},
|
|
292
|
+
handleClose: () => {
|
|
293
|
+
pickerRef.value?.handleClose?.()
|
|
294
|
+
},
|
|
295
|
+
getPickerRef: () => pickerRef.value
|
|
296
|
+
})
|
|
297
|
+
</script>
|
|
298
|
+
|
|
299
|
+
<style scoped>
|
|
300
|
+
.outlined-date-picker {
|
|
301
|
+
position: relative;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.outlined-date-picker__label {
|
|
305
|
+
position: absolute;
|
|
306
|
+
left: -2px;
|
|
307
|
+
padding: 2px 5px;
|
|
308
|
+
border-radius: 2px;
|
|
309
|
+
background-color: #ffffff;
|
|
310
|
+
font-size: 12px;
|
|
311
|
+
line-height: 1;
|
|
312
|
+
transition: color 200ms cubic-bezier(0, 0, 0.2, 1), transform 200ms cubic-bezier(0, 0, 0.2, 1);
|
|
313
|
+
pointer-events: none;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.outlined-date-picker__label--floating {
|
|
317
|
+
top: 18px;
|
|
318
|
+
z-index: 1;
|
|
319
|
+
opacity: 1;
|
|
320
|
+
transform: translate(14px, -6px) scale(1);
|
|
321
|
+
color: var(--el-color-primary);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.outlined-date-picker__label--placeholder {
|
|
325
|
+
top: 50%;
|
|
326
|
+
left: 1px;
|
|
327
|
+
z-index: -1;
|
|
328
|
+
opacity: 0;
|
|
329
|
+
transform: translate(14px, 6px) scale(1);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.outlined-date-picker__label--filled {
|
|
333
|
+
color: var(--el-text-color-regular);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
:deep(.outlined-date-picker__control.el-date-editor) {
|
|
337
|
+
width: 100%;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
:deep(.outlined-date-picker__control .el-input__wrapper) {
|
|
341
|
+
position: relative;
|
|
342
|
+
min-height: inherit;
|
|
343
|
+
height: inherit;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
:deep(.outlined-date-picker__control .el-input__prefix) {
|
|
347
|
+
position: absolute;
|
|
348
|
+
right: 0;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
:deep(.outlined-date-picker__control .el-input__suffix) {
|
|
352
|
+
position: absolute;
|
|
353
|
+
right: 30px;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
:deep(.outlined-date-picker--bordered .el-input__wrapper) {
|
|
357
|
+
box-shadow: none;
|
|
358
|
+
border-radius: 0;
|
|
359
|
+
border-bottom: 1px solid #cccccc;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
:deep(.outlined-date-picker--bordered .el-input__wrapper.is-focus) {
|
|
363
|
+
border-bottom-color: var(--el-color-primary);
|
|
364
|
+
}
|
|
365
|
+
</style>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# OutlinedDatePicker
|
|
2
|
+
|
|
3
|
+
`OutlinedDatePicker` 用来统一项目里带浮动标签样式的日期选择器,避免页面层重复写日期控件高度、标签悬浮、日期禁用和焦点控制逻辑。
|
|
4
|
+
|
|
5
|
+
## 解决的问题
|
|
6
|
+
|
|
7
|
+
- 统一浮动标签日期选择器样式
|
|
8
|
+
- 统一 `v-model:value`、`input`、`update:value` 和 `change` 事件约定
|
|
9
|
+
- 统一 `typeDate / format / valueFormat / disabledDate` 配置方式
|
|
10
|
+
- 自动处理弹层展开时的焦点态和浮动标签状态
|
|
11
|
+
- 通过组件实例直接调用 `focus`、`blur`、`handleOpen`、`handleClose`
|
|
12
|
+
|
|
13
|
+
## 适用场景
|
|
14
|
+
|
|
15
|
+
- 页面需要和 `OutlinedInput / OutlinedSelect` 保持一致视觉语言
|
|
16
|
+
- 表单页中有大量基础日期或日期时间选择器
|
|
17
|
+
- 希望页面只传日期类型和格式配置,不再重复封装统一壳子
|
|
18
|
+
- 需要兼容旧项目里的 `disabledDate="nowDate"` 这类写法
|
|
19
|
+
|
|
20
|
+
## 不适用场景
|
|
21
|
+
|
|
22
|
+
- 需要复杂日期区间联动逻辑并完全接管弹层行为
|
|
23
|
+
- 不是浮动标签风格的时间控件
|
|
24
|
+
- 页面需要不同于 Element Plus 的日期引擎或交互模式
|
|
25
|
+
|
|
26
|
+
## 基础用法
|
|
27
|
+
|
|
28
|
+
```vue
|
|
29
|
+
<template>
|
|
30
|
+
<OutlinedDatePicker
|
|
31
|
+
v-model:value="form.effectDate"
|
|
32
|
+
placeholder="开始生效日期"
|
|
33
|
+
:is-border="true"
|
|
34
|
+
:input-height="40"
|
|
35
|
+
type-date="date"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup lang="ts">
|
|
40
|
+
import { reactive } from 'vue'
|
|
41
|
+
import { OutlinedDatePicker } from '@hbdlzy/ui-core'
|
|
42
|
+
|
|
43
|
+
const form = reactive({
|
|
44
|
+
effectDate: ''
|
|
45
|
+
})
|
|
46
|
+
</script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 日期时间示例
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<template>
|
|
53
|
+
<OutlinedDatePicker
|
|
54
|
+
v-model:value="form.effectiveTime"
|
|
55
|
+
placeholder="上传收益数据开始生效时间"
|
|
56
|
+
:is-border="true"
|
|
57
|
+
type-date="datetime"
|
|
58
|
+
format="YYYY-MM-DD HH:mm:ss"
|
|
59
|
+
/>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<script setup lang="ts">
|
|
63
|
+
import { reactive } from 'vue'
|
|
64
|
+
import { OutlinedDatePicker } from '@hbdlzy/ui-core'
|
|
65
|
+
|
|
66
|
+
const form = reactive({
|
|
67
|
+
effectiveTime: ''
|
|
68
|
+
})
|
|
69
|
+
</script>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 禁用日期示例
|
|
73
|
+
|
|
74
|
+
```vue
|
|
75
|
+
<template>
|
|
76
|
+
<OutlinedDatePicker
|
|
77
|
+
v-model:value="form.effectDate"
|
|
78
|
+
placeholder="开始生效日期"
|
|
79
|
+
type-date="date"
|
|
80
|
+
:disabled-date="'nowDate'"
|
|
81
|
+
:is-border="true"
|
|
82
|
+
/>
|
|
83
|
+
</template>
|
|
84
|
+
|
|
85
|
+
<script setup lang="ts">
|
|
86
|
+
import { reactive } from 'vue'
|
|
87
|
+
import { OutlinedDatePicker } from '@hbdlzy/ui-core'
|
|
88
|
+
|
|
89
|
+
const form = reactive({
|
|
90
|
+
effectDate: ''
|
|
91
|
+
})
|
|
92
|
+
</script>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Props
|
|
96
|
+
|
|
97
|
+
- `value`: 当前值,推荐通过 `v-model:value` 使用
|
|
98
|
+
- `placeholder`: 占位文案,同时默认作为浮动标签文案
|
|
99
|
+
- `label`: 自定义浮动标签文案,未传时回退到 `placeholder`
|
|
100
|
+
- `disabled`: 是否禁用
|
|
101
|
+
- `timeValue`: 是否按带时间场景处理默认时间
|
|
102
|
+
- `typeDate`: 日期控件类型,默认 `date`
|
|
103
|
+
- `format`: 展示格式,默认 `YYYY-MM-DD`
|
|
104
|
+
- `valueFormat`: 值格式,默认回退到 `format`
|
|
105
|
+
- `inputHeight`: 控件高度,默认 `40`
|
|
106
|
+
- `isBorder`: 是否启用底部边框样式
|
|
107
|
+
- `disabledDate`: 日期禁用规则,支持 `nowDate`、日期字符串、时间戳、`Date` 或函数
|
|
108
|
+
- `marginBottom`: 外层容器底部间距,默认 `20`
|
|
109
|
+
- `paddingTop`: 外层容器顶部留白,默认 `20`
|
|
110
|
+
|
|
111
|
+
## Events
|
|
112
|
+
|
|
113
|
+
- `input`: 值变化时触发
|
|
114
|
+
- `update:value`: `v-model:value` 对应更新事件
|
|
115
|
+
- `change`: 用户确认变更时触发
|
|
116
|
+
- `focus`: 聚焦时触发
|
|
117
|
+
- `blur`: 失焦时触发
|
|
118
|
+
- `visible-change`: 面板展开状态变化时触发
|
|
119
|
+
|
|
120
|
+
## Expose
|
|
121
|
+
|
|
122
|
+
- `focus`: 手动聚焦日期控件
|
|
123
|
+
- `blur`: 手动失焦日期控件
|
|
124
|
+
- `handleOpen`: 手动打开日期面板
|
|
125
|
+
- `handleClose`: 手动关闭日期面板
|
|
126
|
+
- `getPickerRef`: 获取底层 `el-date-picker` 实例
|
|
127
|
+
|
|
128
|
+
## 透传规则
|
|
129
|
+
|
|
130
|
+
- 未被组件显式声明的属性,会自动透传给内部 `el-date-picker`
|
|
131
|
+
- 适合继续传 `clearable`、`editable`、`default-time`、`shortcuts`、`unlink-panels` 等 Element Plus 原生能力
|
|
132
|
+
|
|
133
|
+
## 推荐约定
|
|
134
|
+
|
|
135
|
+
- 普通日期和日期时间选择器优先使用 `OutlinedDatePicker`
|
|
136
|
+
- 默认通过 `typeDate + format` 收敛常见场景
|
|
137
|
+
- 自定义日期禁用规则优先使用 `disabledDate`,不要在页面层重复封装相同逻辑
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import OutlinedDatePicker from './OutlinedDatePicker.vue'
|
|
2
|
+
|
|
3
|
+
export default OutlinedDatePicker
|
|
4
|
+
|
|
5
|
+
export type {
|
|
6
|
+
OutlinedDatePickerCssValue,
|
|
7
|
+
OutlinedDatePickerDisabledDate,
|
|
8
|
+
OutlinedDatePickerExpose,
|
|
9
|
+
OutlinedDatePickerProps,
|
|
10
|
+
OutlinedDatePickerValue
|
|
11
|
+
} from './OutlinedDatePicker.types'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type OutlinedDateTimePickerCssValue = string | number
|
|
2
|
+
|
|
3
|
+
export type OutlinedDateTimePickerValue = string
|
|
4
|
+
|
|
5
|
+
export type OutlinedDateTimePickerDisabledDate =
|
|
6
|
+
| string
|
|
7
|
+
| number
|
|
8
|
+
| Date
|
|
9
|
+
| ((date: Date) => boolean)
|
|
10
|
+
|
|
11
|
+
export interface OutlinedDateTimePickerProps {
|
|
12
|
+
value?: OutlinedDateTimePickerValue
|
|
13
|
+
placeholder?: string
|
|
14
|
+
label?: string
|
|
15
|
+
inputHeight?: number
|
|
16
|
+
isBorder?: boolean
|
|
17
|
+
disabledDate?: OutlinedDateTimePickerDisabledDate
|
|
18
|
+
separatorText?: string
|
|
19
|
+
timePlaceholder?: string
|
|
20
|
+
clearable?: boolean
|
|
21
|
+
marginBottom?: OutlinedDateTimePickerCssValue
|
|
22
|
+
paddingTop?: OutlinedDateTimePickerCssValue
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface OutlinedDateTimePickerExpose {
|
|
26
|
+
focusDate: () => void
|
|
27
|
+
focusTime: () => void
|
|
28
|
+
blurDate: () => void
|
|
29
|
+
blurTime: () => void
|
|
30
|
+
openDatePanel: () => void
|
|
31
|
+
openTimePanel: () => void
|
|
32
|
+
getDatePickerRef: () => unknown | null
|
|
33
|
+
getTimePickerRef: () => unknown | null
|
|
34
|
+
}
|