Skip to content

Commit 3c1023c

Browse files
fix: 🐛 修复 DatetimePicker 区间选择时无法选择绑定值范围以外的时间的问题
Closes: #1170
1 parent 66f796e commit 3c1023c

4 files changed

Lines changed: 37 additions & 92 deletions

File tree

src/uni_modules/wot-design-uni/components/wd-datetime-picker-view/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ export const datetimePickerViewProps = {
8484
/**
8585
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
8686
*/
87-
immediateChange: makeBooleanProp(false),
88-
startSymbol: makeBooleanProp(false)
87+
immediateChange: makeBooleanProp(false)
8988
}
9089

9190
export type DatetimePickerViewColumnType = 'year' | 'month' | 'date' | 'hour' | 'minute' | 'second'
@@ -99,7 +98,7 @@ export type DatetimePickerViewFilter = (type: DatetimePickerViewColumnType, valu
9998

10099
export type DatetimePickerViewFormatter = (type: string, value: string) => string
101100

102-
export type DatetimePickerViewColumnFormatter = (picker: DatetimePickerViewInstance) => DatetimePickerViewOption[][]
101+
export type DatetimePickerViewColumnFormatter = (picker: DatetimePickerViewExpose) => DatetimePickerViewOption[][]
103102

104103
export type DatetimePickerViewProps = ExtractPropTypes<typeof datetimePickerViewProps>
105104

src/uni_modules/wot-design-uni/components/wd-datetime-picker-view/util.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@ import { type DateTimeType } from './types'
44
* @description 根据传入的值和类型,获取当前的选项数组,便于传入 pickerView
55
* @param value
66
* @param type picker类型
7+
* @param useSecond 是否使用秒,仅在 time 和 datetime 类型下生效
78
*/
8-
export function getPickerValue(value: string | number, type: DateTimeType) {
9+
export function getPickerValue(value: string | number, type: DateTimeType, useSecond: boolean = false) {
910
const values: number[] = []
1011
const date = new Date(value)
1112
if (type === 'time') {
1213
const pair = String(value).split(':')
1314
values.push(parseInt(pair[0]), parseInt(pair[1]))
14-
if (pair[2]) {
15+
if (useSecond && pair[2]) {
1516
values.push(parseInt(pair[2]))
1617
}
1718
} else {
1819
values.push(date.getFullYear(), date.getMonth() + 1)
1920
if (type === 'date') {
2021
values.push(date.getDate())
2122
} else if (type === 'datetime') {
22-
values.push(date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())
23+
values.push(date.getDate(), date.getHours(), date.getMinutes())
24+
if (useSecond) {
25+
values.push(date.getSeconds())
26+
}
2327
}
2428
}
2529
return values

src/uni_modules/wot-design-uni/components/wd-datetime-picker-view/wd-datetime-picker-view.vue

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default {
2727
<script lang="ts" setup>
2828
import wdPickerView from '../wd-picker-view/wd-picker-view.vue'
2929
import { getCurrentInstance, onBeforeMount, ref, watch } from 'vue'
30-
import { debounce, isFunction, isDef, padZero, range, isArray, isString } from '../common/util'
30+
import { debounce, isDef, padZero, range, isArray, isString } from '../common/util'
3131
import { datetimePickerViewProps, type DatetimePickerViewColumnType, type DatetimePickerViewOption, type DatetimePickerViewExpose } from './types'
3232
import type { PickerViewInstance } from '../wd-picker-view/types'
3333
import { getPickerValue } from './util'
@@ -80,7 +80,6 @@ const { proxy } = getCurrentInstance() as any
8080
* @description updateValue 防抖函数的占位符
8181
*/
8282
const updateValue = debounce(() => {
83-
// 只有等created hook初始化数据之后,observer才能执行此操作
8483
if (!created.value) return
8584
const val = correctValue(props.modelValue)
8685
const isEqual = val === innerValue.value
@@ -109,47 +108,16 @@ watch(
109108
if (type.indexOf(target) === -1) {
110109
console.error(`type must be one of ${type}`)
111110
}
112-
// 每次type更新时都需要刷新整个列表
113-
updateValue()
114-
},
115-
{ deep: true, immediate: true }
116-
)
117-
118-
watch(
119-
() => props.filter,
120-
(fn) => {
121-
if (fn && !isFunction(fn)) {
122-
console.error('The type of filter must be Function')
123-
}
124-
updateValue()
125-
},
126-
{ deep: true, immediate: true }
127-
)
128-
129-
watch(
130-
() => props.formatter,
131-
(fn) => {
132-
if (fn && !isFunction(fn)) {
133-
console.error('The type of formatter must be Function')
134-
}
135-
updateValue()
136-
},
137-
{ deep: true, immediate: true }
138-
)
139-
140-
watch(
141-
() => props.columnFormatter,
142-
(fn) => {
143-
if (fn && !isFunction(fn)) {
144-
console.error('The type of columnFormatter must be Function')
145-
}
146-
updateValue()
147111
},
148112
{ deep: true, immediate: true }
149113
)
150114
151115
watch(
152116
[
117+
() => props.type,
118+
() => props.filter,
119+
() => props.formatter,
120+
() => props.columnFormatter,
153121
() => props.minDate,
154122
() => props.maxDate,
155123
() => props.minHour,
@@ -392,7 +360,7 @@ function getBoundary(type: 'min' | 'max', innerValue: number) {
392360
* @return {Array}
393361
*/
394362
function updateColumnValue(value: string | number) {
395-
const values = getPickerValue(value, props.type)
363+
const values = getPickerValue(value, props.type, props.useSecond)
396364
// 更新pickerView的value,columns
397365
if (props.modelValue !== value) {
398366
emit('update:modelValue', value)
@@ -486,8 +454,8 @@ function columnChange(picker: PickerViewInstance) {
486454
/** 根据计算选中项的时间戳,重新计算所有的选项列表 */
487455
// 更新选中时间戳
488456
innerValue.value = correctValue(value)
489-
// 根据innerValue获取最新的时间表,重新生成对应的数据源
490457
458+
// 根据innerValue获取最新的时间表,重新生成对应的数据源
491459
const newColumns = updateColumns()
492460
// 深拷贝联动之前的选中项
493461
const selectedIndex = picker.getSelectedIndex().slice(0)

src/uni_modules/wot-design-uni/components/wd-datetime-picker/wd-datetime-picker.vue

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<wd-cell
44
v-if="!$slots.default"
55
:title="label"
6-
:required="isRequired"
76
:size="size"
87
:title-width="labelWidth"
98
:prop="prop"
@@ -101,7 +100,7 @@
101100
:label-key="labelKey"
102101
:formatter="formatter"
103102
:filter="filter"
104-
:column-formatter="isArray(modelValue) ? customColumnFormatter : undefined"
103+
:column-formatter="isArray(modelValue) ? startColumnFormatter : undefined"
105104
:max-hour="maxHour"
106105
:min-hour="minHour"
107106
:max-date="maxDate"
@@ -111,7 +110,6 @@
111110
:use-second="useSecond"
112111
:min-second="minSecond"
113112
:max-second="maxSecond"
114-
:start-symbol="true"
115113
:immediate-change="immediateChange"
116114
@change="onChangeStart"
117115
@pickstart="onPickStart"
@@ -131,7 +129,7 @@
131129
:label-key="labelKey"
132130
:formatter="formatter"
133131
:filter="filter"
134-
:column-formatter="isArray(modelValue) ? customColumnFormatter : undefined"
132+
:column-formatter="isArray(modelValue) ? endColumnFormatter : undefined"
135133
:max-hour="maxHour"
136134
:min-hour="minHour"
137135
:max-date="maxDate"
@@ -141,7 +139,6 @@
141139
:use-second="useSecond"
142140
:min-second="minSecond"
143141
:max-second="maxSecond"
144-
:start-symbol="false"
145142
:immediate-change="immediateChange"
146143
@change="onChangeEnd"
147144
@pickstart="onPickStart"
@@ -170,13 +167,7 @@ import wdDatetimePickerView from '../wd-datetime-picker-view/wd-datetime-picker-
170167
import wdCell from '../wd-cell/wd-cell.vue'
171168
import { computed, getCurrentInstance, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue'
172169
import { deepClone, isArray, isDef, isEqual, isFunction, padZero } from '../common/util'
173-
import {
174-
type DatetimePickerViewInstance,
175-
type DatetimePickerViewColumnFormatter,
176-
type DatetimePickerViewColumnType
177-
} from '../wd-datetime-picker-view/types'
178-
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
179-
import { useParent } from '../composables/useParent'
170+
import { type DatetimePickerViewInstance, type DatetimePickerViewColumnType, type DatetimePickerViewExpose } from '../wd-datetime-picker-view/types'
180171
import { useTranslate } from '../composables/useTranslate'
181172
import { datetimePickerProps, type DatetimePickerExpose } from './types'
182173
import dayjs from '../../dayjs'
@@ -304,31 +295,6 @@ watch(
304295
}
305296
)
306297
307-
const { parent: form } = useParent(FORM_KEY)
308-
309-
// 表单校验错误信息
310-
const errorMessage = computed(() => {
311-
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
312-
return form.errorMessages[props.prop]
313-
} else {
314-
return ''
315-
}
316-
})
317-
318-
// 是否展示必填
319-
const isRequired = computed(() => {
320-
let formRequired = false
321-
if (form && form.props.rules) {
322-
const rules = form.props.rules
323-
for (const key in rules) {
324-
if (Object.prototype.hasOwnProperty.call(rules, key) && key === props.prop && Array.isArray(rules[key])) {
325-
formRequired = rules[key].some((rule: FormItemRule) => rule.required)
326-
}
327-
}
328-
}
329-
return props.required || props.rules.some((rule) => rule.required) || formRequired
330-
})
331-
332298
// 是否展示清除按钮
333299
const showClear = computed(() => {
334300
return (
@@ -361,7 +327,6 @@ function handleBoundaryValue(
361327
boundary: number[]
362328
): boolean {
363329
const { type, useSecond } = props
364-
365330
switch (type) {
366331
case 'datetime': {
367332
const [year, month, date, hour, minute, second] = boundary
@@ -440,21 +405,28 @@ function handleBoundaryValue(
440405
return false
441406
}
442407
408+
function startColumnFormatter(picker: DatetimePickerViewExpose) {
409+
return customColumnFormatter(picker, 'start')
410+
}
411+
412+
function endColumnFormatter(picker: DatetimePickerViewExpose) {
413+
return customColumnFormatter(picker, 'end')
414+
}
415+
443416
/**
444417
* @description 自定义列项筛选规则
445418
*/
446-
const customColumnFormatter: DatetimePickerViewColumnFormatter = (picker) => {
419+
const customColumnFormatter = (picker: DatetimePickerViewExpose, pickerType: 'start' | 'end') => {
447420
if (!picker) return []
448421
449422
const { type } = props
450-
const { startSymbol, formatter } = picker
423+
const startSymbol = pickerType === 'start'
424+
const { formatter } = props
451425
const start = picker.correctValue(innerValue.value)
452426
const end = picker.correctValue(endInnerValue.value)
453-
454-
const currentValue = startSymbol ? getPickerValue(start, type) : getPickerValue(end, type)
455-
const boundary = startSymbol ? getPickerValue(end, type) : getPickerValue(start, type)
427+
const currentValue = startSymbol ? getPickerValue(start, type, props.useSecond) : getPickerValue(end, type, props.useSecond)
428+
const boundary = startSymbol ? getPickerValue(end, type, props.useSecond) : getPickerValue(start, type, props.useSecond)
456429
const columns = picker.getOriginColumns()
457-
458430
return columns.map((column, _) => {
459431
return column.values.map((value) => {
460432
const disabled = handleBoundaryValue(startSymbol, column.type, value, currentValue, boundary)
@@ -489,7 +461,7 @@ function getSelects(picker: 'before' | 'after') {
489461
let value = picker === 'before' ? innerValue.value : endInnerValue.value
490462
let selected: number[] = []
491463
if (value) {
492-
selected = getPickerValue(value, props.type)
464+
selected = getPickerValue(value, props.type, props.useSecond)
493465
}
494466
495467
let selects = selected.map((value) => {
@@ -564,8 +536,10 @@ function onChangeStart({ value }: { value: number | string }) {
564536
565537
if (region.value) {
566538
// 区间选择才需要处理边界值
567-
const currentArray = getPickerValue(value, props.type)
568-
const boundaryArray = getPickerValue(endInnerValue.value, props.type)
539+
// 区间选择才需要处理边界值
540+
const currentArray = getPickerValue(value, props.type, props.useSecond)
541+
const boundaryArray = getPickerValue(endInnerValue.value, props.type, props.useSecond)
542+
569543
const columns = datetimePickerView.value.getOriginColumns()
570544
571545
// 检查是否有任何列超出边界

0 commit comments

Comments
 (0)