1
0
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:
chenjiahan 2022-02-15 15:08:59 +08:00
parent 3920ebe25b
commit e8ffc80dc6
5 changed files with 103 additions and 107 deletions
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);