mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(DatePicker): date columns calculation
This commit is contained in:
parent
3920ebe25b
commit
e8ffc80dc6
packages/vant/src
@ -1,11 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
watch,
|
|
||||||
computed,
|
computed,
|
||||||
nextTick,
|
|
||||||
defineComponent,
|
defineComponent,
|
||||||
type PropType,
|
type PropType,
|
||||||
ExtractPropTypes,
|
type ExtractPropTypes,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
@ -20,13 +18,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
times,
|
times,
|
||||||
sharedProps,
|
sharedProps,
|
||||||
getTrueValue,
|
|
||||||
getMonthEndDay,
|
getMonthEndDay,
|
||||||
pickerInheritKeys,
|
pickerInheritKeys,
|
||||||
} from '../datetime-picker/utils';
|
} from '../datetime-picker/utils';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { Picker, PickerOption } from '../picker';
|
import { Picker } from '../picker';
|
||||||
|
|
||||||
const currentYear = new Date().getFullYear();
|
const currentYear = new Date().getFullYear();
|
||||||
const [name] = createNamespace('date-picker');
|
const [name] = createNamespace('date-picker');
|
||||||
@ -61,104 +58,105 @@ export default defineComponent({
|
|||||||
emits: ['confirm', 'cancel', 'change', 'update:modelValue'],
|
emits: ['confirm', 'cancel', 'change', 'update:modelValue'],
|
||||||
|
|
||||||
setup(props, { emit, slots }) {
|
setup(props, { emit, slots }) {
|
||||||
const formatValue = (value?: Date) => {
|
const currentValues = ref<string[]>([]);
|
||||||
if (isDate(value)) {
|
|
||||||
const timestamp = clamp(
|
|
||||||
value.getTime(),
|
|
||||||
props.minDate.getTime(),
|
|
||||||
props.maxDate.getTime()
|
|
||||||
);
|
|
||||||
return new Date(timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
// const setValue = (type: DatePickerColumnType, newValue: string) => {
|
||||||
|
// const index = props.columnsType.indexOf(type);
|
||||||
|
// currentValues.value[index] = newValue;
|
||||||
|
// };
|
||||||
|
|
||||||
|
const getValue = (type: DatePickerColumnType) => {
|
||||||
|
const index = props.columnsType.indexOf(type);
|
||||||
|
return +currentValues.value[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentDate = ref(formatValue(props.modelValue));
|
const formatValue = (value: Date) => {
|
||||||
|
const timestamp = clamp(
|
||||||
const getBoundary = (type: 'max' | 'min', value: Date) => {
|
value.getTime(),
|
||||||
const boundary = props[`${type}Date` as const];
|
props.minDate.getTime(),
|
||||||
const year = boundary.getFullYear();
|
props.maxDate.getTime()
|
||||||
let month = 1;
|
|
||||||
let date = 1;
|
|
||||||
|
|
||||||
if (type === 'max') {
|
|
||||||
month = 12;
|
|
||||||
date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.getFullYear() === year) {
|
|
||||||
month = boundary.getMonth() + 1;
|
|
||||||
|
|
||||||
if (value.getMonth() + 1 === month) {
|
|
||||||
date = boundary.getDate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
[`${type}Year`]: year,
|
|
||||||
[`${type}Month`]: month,
|
|
||||||
[`${type}Date`]: date,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const ranges = computed(() => {
|
|
||||||
const { maxYear, maxDate, maxMonth } = getBoundary(
|
|
||||||
'max',
|
|
||||||
currentDate.value || props.minDate
|
|
||||||
);
|
|
||||||
const { minYear, minDate, minMonth } = getBoundary(
|
|
||||||
'min',
|
|
||||||
currentDate.value || props.minDate
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const date = new Date(timestamp);
|
||||||
return props.columnsType.map((type) => {
|
return props.columnsType.map((type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'year':
|
case 'year':
|
||||||
return {
|
return String(date.getFullYear());
|
||||||
type: 'year',
|
|
||||||
range: [minYear, maxYear],
|
|
||||||
};
|
|
||||||
case 'month':
|
case 'month':
|
||||||
return {
|
return padZero(date.getMonth() + 1);
|
||||||
type: 'month',
|
|
||||||
range: [minMonth, maxMonth],
|
|
||||||
};
|
|
||||||
case 'day':
|
case 'day':
|
||||||
return {
|
default:
|
||||||
type: 'day',
|
return padZero(date.getDate());
|
||||||
range: [minDate, maxDate],
|
}
|
||||||
};
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (props.modelValue) {
|
||||||
|
currentValues.value = formatValue(props.modelValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
const genOptions = (
|
||||||
|
min: number,
|
||||||
|
max: number,
|
||||||
|
type: DatePickerColumnType
|
||||||
|
) => {
|
||||||
|
const options = times(max - min + 1, (index) => {
|
||||||
|
const value = padZero(min + index);
|
||||||
|
return props.formatter(type, {
|
||||||
|
text: value,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return props.filter ? props.filter(type, options) : options;
|
||||||
|
};
|
||||||
|
|
||||||
|
const genYearOptions = () => {
|
||||||
|
const minYear = props.minDate.getFullYear();
|
||||||
|
const maxYear = props.maxDate.getFullYear();
|
||||||
|
return genOptions(minYear, maxYear, 'year');
|
||||||
|
};
|
||||||
|
|
||||||
|
const isMaxYear = (year: number) => year === props.maxDate.getFullYear();
|
||||||
|
const isMaxMonth = (month: number) =>
|
||||||
|
month === props.maxDate.getMonth() + 1;
|
||||||
|
|
||||||
|
const genMonthOptions = () => {
|
||||||
|
if (isMaxYear(getValue('year'))) {
|
||||||
|
return genOptions(1, props.maxDate.getMonth() + 1, 'month');
|
||||||
|
}
|
||||||
|
return genOptions(1, 12, 'month');
|
||||||
|
};
|
||||||
|
|
||||||
|
const genDayOptions = () => {
|
||||||
|
const year = getValue('year');
|
||||||
|
const month = getValue('month');
|
||||||
|
|
||||||
|
let maxDate = getMonthEndDay(year, month);
|
||||||
|
if (isMaxYear(year) && isMaxMonth(month)) {
|
||||||
|
maxDate = props.maxDate.getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return genOptions(1, maxDate, 'day');
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = computed(() =>
|
||||||
|
props.columnsType.map((type) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'year':
|
||||||
|
return genYearOptions();
|
||||||
|
case 'month':
|
||||||
|
return genMonthOptions();
|
||||||
|
case 'day':
|
||||||
|
return genDayOptions();
|
||||||
default:
|
default:
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`[Vant] DatePicker: unsupported columns type: ${type}`
|
`[Vant] DatePicker: unsupported columns type: ${type}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const columns = computed(() =>
|
|
||||||
ranges.value.map(({ type, range }) => {
|
|
||||||
const options = times(
|
|
||||||
range[1] - range[0] + 1,
|
|
||||||
(index): PickerOption => {
|
|
||||||
const value = padZero(range[0] + index);
|
|
||||||
return props.formatter(type, {
|
|
||||||
text: value,
|
|
||||||
value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (props.filter) {
|
|
||||||
return props.filter(type, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// watch(currentDate, (value, oldValue) =>
|
// watch(currentValues, (value, oldValue) =>
|
||||||
// emit('update:modelValue', oldValue ? value : null)
|
// emit('update:modelValue', oldValue ? value : null)
|
||||||
// );
|
// );
|
||||||
|
|
||||||
@ -167,8 +165,8 @@ export default defineComponent({
|
|||||||
// (value) => {
|
// (value) => {
|
||||||
// value = formatValue(value);
|
// value = formatValue(value);
|
||||||
|
|
||||||
// if (value && value.valueOf() !== currentDate.value?.valueOf()) {
|
// if (value && value.valueOf() !== currentValues.value?.valueOf()) {
|
||||||
// currentDate.value = value;
|
// currentValues.value = value;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// );
|
// );
|
||||||
@ -180,6 +178,7 @@ export default defineComponent({
|
|||||||
return () => (
|
return () => (
|
||||||
<Picker
|
<Picker
|
||||||
v-slots={slots}
|
v-slots={slots}
|
||||||
|
v-model={currentValues.value}
|
||||||
columns={columns.value}
|
columns={columns.value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
|
@ -32,7 +32,7 @@ export default {
|
|||||||
const currentDate = ref(new Date(2021, 0, 1));
|
const currentDate = ref(new Date(2021, 0, 1));
|
||||||
return {
|
return {
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -68,7 +68,7 @@ export default {
|
|||||||
const currentDate = ref(new Date(2021, 0, 1));
|
const currentDate = ref(new Date(2021, 0, 1));
|
||||||
return {
|
return {
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -107,7 +107,7 @@ export default {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
formatter,
|
formatter,
|
||||||
currentDate,
|
currentDate,
|
||||||
};
|
};
|
||||||
@ -144,7 +144,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
filter,
|
filter,
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentTime,
|
currentTime,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@ export default {
|
|||||||
const currentDate = ref(new Date(2021, 0, 1));
|
const currentDate = ref(new Date(2021, 0, 1));
|
||||||
return {
|
return {
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -70,7 +70,7 @@ export default {
|
|||||||
const currentDate = ref(new Date(2021, 0, 1));
|
const currentDate = ref(new Date(2021, 0, 1));
|
||||||
return {
|
return {
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -111,7 +111,7 @@ export default {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
formatter,
|
formatter,
|
||||||
currentDate,
|
currentDate,
|
||||||
};
|
};
|
||||||
@ -150,7 +150,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
filter,
|
filter,
|
||||||
minDate: new Date(2020, 0, 1),
|
minDate: new Date(2020, 0, 1),
|
||||||
maxDate: new Date(2025, 10, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentTime,
|
currentTime,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -28,7 +28,7 @@ const t = useTranslate({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const minDate = new Date(2020, 0, 1);
|
const minDate = new Date(2020, 0, 1);
|
||||||
const maxDate = new Date(2025, 10, 1);
|
const maxDate = new Date(2025, 5, 1);
|
||||||
const basicDate = ref(new Date(2021, 0, 1));
|
const basicDate = ref(new Date(2021, 0, 1));
|
||||||
const yearMonthDate = ref(new Date(2021, 0, 1));
|
const yearMonthDate = ref(new Date(2021, 0, 1));
|
||||||
const formatterDate = ref(new Date(2021, 0, 1));
|
const formatterDate = ref(new Date(2021, 0, 1));
|
||||||
|
@ -22,7 +22,7 @@ import {
|
|||||||
} from '../datetime-picker/utils';
|
} from '../datetime-picker/utils';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { Picker, PickerOption } from '../picker';
|
import { Picker } from '../picker';
|
||||||
|
|
||||||
const [name] = createNamespace('time-picker');
|
const [name] = createNamespace('time-picker');
|
||||||
|
|
||||||
@ -73,16 +73,13 @@ export default defineComponent({
|
|||||||
|
|
||||||
const columns = computed(() =>
|
const columns = computed(() =>
|
||||||
ranges.value.map(({ type, range }) => {
|
ranges.value.map(({ type, range }) => {
|
||||||
const options = times(
|
const options = times(range[1] - range[0] + 1, (index) => {
|
||||||
range[1] - range[0] + 1,
|
const value = padZero(range[0] + index);
|
||||||
(index): PickerOption => {
|
return props.formatter(type, {
|
||||||
const value = padZero(range[0] + index);
|
text: value,
|
||||||
return props.formatter(type, {
|
value,
|
||||||
text: value,
|
});
|
||||||
value,
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (props.filter) {
|
if (props.filter) {
|
||||||
return props.filter(type, options);
|
return props.filter(type, options);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user