mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
types(DatetimePicker): use tsx (#8181)
This commit is contained in:
parent
d092d669f2
commit
7daca89102
@ -1,15 +1,23 @@
|
||||
import { ref, watch, computed, nextTick, onMounted } from 'vue';
|
||||
import { ref, watch, computed, nextTick, onMounted, PropType } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { isDate } from '../utils/validate/date';
|
||||
import { pick, padZero, createNamespace } from '../utils';
|
||||
import { times, sharedProps, getTrueValue, getMonthEndDay } from './utils';
|
||||
import { pick, range, padZero, createNamespace } from '../utils';
|
||||
import {
|
||||
times,
|
||||
ColumnType,
|
||||
pickerKeys,
|
||||
sharedProps,
|
||||
getTrueValue,
|
||||
getMonthEndDay,
|
||||
DatetimePickerType,
|
||||
} from './utils';
|
||||
|
||||
// Composition
|
||||
import { useExpose } from '../composables/use-expose';
|
||||
|
||||
// Components
|
||||
import Picker, { pickerProps } from '../picker';
|
||||
import Picker from '../picker';
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const [createComponent] = createNamespace('date-picker');
|
||||
@ -17,17 +25,18 @@ const [createComponent] = createNamespace('date-picker');
|
||||
export default createComponent({
|
||||
props: {
|
||||
...sharedProps,
|
||||
modelValue: Date as PropType<Date>,
|
||||
type: {
|
||||
type: String,
|
||||
type: String as PropType<DatetimePickerType>,
|
||||
default: 'datetime',
|
||||
},
|
||||
minDate: {
|
||||
type: Date,
|
||||
type: Date as PropType<Date>,
|
||||
default: () => new Date(currentYear - 10, 0, 1),
|
||||
validator: isDate,
|
||||
},
|
||||
maxDate: {
|
||||
type: Date,
|
||||
type: Date as PropType<Date>,
|
||||
default: () => new Date(currentYear + 10, 11, 31),
|
||||
validator: isDate,
|
||||
},
|
||||
@ -36,22 +45,23 @@ export default createComponent({
|
||||
emits: ['confirm', 'cancel', 'change', 'update:modelValue'],
|
||||
|
||||
setup(props, { emit, slots }) {
|
||||
const formatValue = (value) => {
|
||||
if (!isDate(value)) {
|
||||
value = props.minDate;
|
||||
const formatValue = (value?: Date) => {
|
||||
if (isDate(value)) {
|
||||
const timestamp = range(
|
||||
value.getTime(),
|
||||
props.minDate.getTime(),
|
||||
props.maxDate.getTime()
|
||||
);
|
||||
return new Date(timestamp);
|
||||
}
|
||||
|
||||
value = Math.max(value, props.minDate.getTime());
|
||||
value = Math.min(value, props.maxDate.getTime());
|
||||
|
||||
return new Date(value);
|
||||
return props.minDate;
|
||||
};
|
||||
|
||||
const picker = ref();
|
||||
const currentDate = ref(formatValue(props.modelValue));
|
||||
|
||||
const getBoundary = (type, value) => {
|
||||
const boundary = props[`${type}Date`];
|
||||
const getBoundary = (type: 'max' | 'min', value: Date) => {
|
||||
const boundary = props[`${type}Date` as const];
|
||||
const year = boundary.getFullYear();
|
||||
let month = 1;
|
||||
let date = 1;
|
||||
@ -98,7 +108,7 @@ export default createComponent({
|
||||
currentDate.value
|
||||
);
|
||||
|
||||
let result = [
|
||||
let result: Array<{ type: ColumnType; range: number[] }> = [
|
||||
{
|
||||
type: 'year',
|
||||
range: [minYear, maxYear],
|
||||
@ -205,7 +215,7 @@ export default createComponent({
|
||||
const { type } = props;
|
||||
const indexes = picker.value.getIndexes();
|
||||
|
||||
const getValue = (type) => {
|
||||
const getValue = (type: ColumnType) => {
|
||||
let index = 0;
|
||||
originColumns.value.forEach((column, columnIndex) => {
|
||||
if (type === column.type) {
|
||||
@ -301,11 +311,10 @@ export default createComponent({
|
||||
v-slots={slots}
|
||||
ref={picker}
|
||||
columns={columns.value}
|
||||
readonly={props.readonly}
|
||||
onChange={onChange}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
{...pick(props, Object.keys(pickerProps))}
|
||||
{...pick(props, pickerKeys)}
|
||||
/>
|
||||
);
|
||||
},
|
@ -284,8 +284,8 @@ export default {
|
||||
| show-toolbar | Whether to show toolbar | _boolean_ | `true` |
|
||||
| loading | Whether to show loading prompt | _boolean_ | `false` |
|
||||
| readonly | Whether to be readonly | _boolean_ | `false` |
|
||||
| filter | Option filter | _(type, vals) => vals_ | - |
|
||||
| formatter | Option text formatter | _(type, val) => val_ | - |
|
||||
| filter | Option filter | _(type: string, values: string[]) => string[]_ | - |
|
||||
| formatter | Option text formatter | _(type: string, value: string) => string_ | - |
|
||||
| columns-order | Array for ordering columns, where item can be set to<br> `year`, `month`, `day`, `hour` and `minute` | _string[]_ | - |
|
||||
| item-height | Option height, supports `px` `vw` `vh` `rem` unit, default `px` | _number \| string_ | `44` |
|
||||
| visible-item-count | Count of visible columns | _number \| string_ | `6` |
|
||||
|
@ -293,8 +293,8 @@ export default {
|
||||
| show-toolbar | 是否显示顶部栏 | _boolean_ | `true` |
|
||||
| loading | 是否显示加载状态 | _boolean_ | `false` |
|
||||
| readonly | 是否为只读状态,只读状态下无法切换选项 | _boolean_ | `false` |
|
||||
| filter | 选项过滤函数 | _(type, vals) => vals_ | - |
|
||||
| formatter | 选项格式化函数 | _(type, val) => val_ | - |
|
||||
| filter | 选项过滤函数 | _(type: string, values: string[]) => string[]_ | - |
|
||||
| formatter | 选项格式化函数 | _(type: string, value: string) => string_ | - |
|
||||
| columns-order | 自定义列排序数组, 子项可选值为<br> `year`、`month`、`day`、`hour`、`minute` | _string[]_ | - |
|
||||
| item-height | 选项高度,支持 `px` `vw` `vh` `rem` 单位,默认 `px` | _number \| string_ | `44` |
|
||||
| visible-item-count | 可见的选项个数 | _number \| string_ | `6` |
|
||||
|
@ -1,20 +1,27 @@
|
||||
import { ref, watch, computed, nextTick, onMounted } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { pick, range, padZero, createNamespace } from '../utils';
|
||||
import { times, sharedProps } from './utils';
|
||||
import {
|
||||
pick,
|
||||
range,
|
||||
padZero,
|
||||
createNamespace,
|
||||
ComponentInstance,
|
||||
} from '../utils';
|
||||
import { times, sharedProps, pickerKeys } from './utils';
|
||||
|
||||
// Composition
|
||||
import { useExpose } from '../composables/use-expose';
|
||||
|
||||
// Components
|
||||
import Picker, { pickerProps } from '../picker';
|
||||
import Picker from '../picker';
|
||||
|
||||
const [createComponent] = createNamespace('time-picker');
|
||||
|
||||
export default createComponent({
|
||||
props: {
|
||||
...sharedProps,
|
||||
modelValue: String,
|
||||
minHour: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
@ -36,7 +43,7 @@ export default createComponent({
|
||||
emits: ['confirm', 'cancel', 'change', 'update:modelValue'],
|
||||
|
||||
setup(props, { emit, slots }) {
|
||||
const formatValue = (value) => {
|
||||
const formatValue = (value?: string) => {
|
||||
const { minHour, maxHour, maxMinute, minMinute } = props;
|
||||
|
||||
if (!value) {
|
||||
@ -44,13 +51,13 @@ export default createComponent({
|
||||
}
|
||||
|
||||
let [hour, minute] = value.split(':');
|
||||
hour = padZero(range(hour, minHour, maxHour));
|
||||
minute = padZero(range(minute, minMinute, maxMinute));
|
||||
hour = padZero(range(+hour, +minHour, +maxHour));
|
||||
minute = padZero(range(+minute, +minMinute, +maxMinute));
|
||||
|
||||
return `${hour}:${minute}`;
|
||||
};
|
||||
|
||||
const picker = ref();
|
||||
const picker = ref<ComponentInstance>();
|
||||
const currentDate = ref(formatValue(props.modelValue));
|
||||
|
||||
const ranges = computed(() => [
|
||||
@ -97,12 +104,12 @@ export default createComponent({
|
||||
];
|
||||
|
||||
nextTick(() => {
|
||||
picker.value.setValues(values);
|
||||
picker.value!.setValues(values);
|
||||
});
|
||||
};
|
||||
|
||||
const updateInnerValue = () => {
|
||||
const [hourIndex, minuteIndex] = picker.value.getIndexes();
|
||||
const [hourIndex, minuteIndex] = picker.value!.getIndexes();
|
||||
const [hourColumn, minuteColumn] = originColumns.value;
|
||||
|
||||
const hour = hourColumn.values[hourIndex] || hourColumn.values[0];
|
||||
@ -173,11 +180,10 @@ export default createComponent({
|
||||
v-slots={slots}
|
||||
ref={picker}
|
||||
columns={columns.value}
|
||||
readonly={props.readonly}
|
||||
onChange={onChange}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
{...pick(props, Object.keys(pickerProps))}
|
||||
{...pick(props, pickerKeys)}
|
||||
/>
|
||||
);
|
||||
},
|
@ -1,5 +1,5 @@
|
||||
import { ref } from 'vue';
|
||||
import { pick, createNamespace } from '../utils';
|
||||
import { pick, createNamespace, ComponentInstance } from '../utils';
|
||||
import { useExpose } from '../composables/use-expose';
|
||||
import TimePicker from './TimePicker';
|
||||
import DatePicker from './DatePicker';
|
||||
@ -13,10 +13,11 @@ export default createComponent({
|
||||
props: {
|
||||
...TimePicker.props,
|
||||
...DatePicker.props,
|
||||
modelValue: [String, Date],
|
||||
},
|
||||
|
||||
setup(props, { attrs, slots }) {
|
||||
const root = ref();
|
||||
const root = ref<ComponentInstance>();
|
||||
|
||||
useExpose({
|
||||
getPicker: () => root.value?.getPicker(),
|
@ -1,20 +1,34 @@
|
||||
import { PropType } from 'vue';
|
||||
import { isNaN } from '../utils/validate/number';
|
||||
import { pickerProps } from '../picker';
|
||||
|
||||
export type ColumnType = 'year' | 'month' | 'day' | 'hour' | 'minute';
|
||||
|
||||
export type DatetimePickerType =
|
||||
| 'date'
|
||||
| 'time'
|
||||
| 'datetime'
|
||||
| 'datehour'
|
||||
| 'month-day'
|
||||
| 'year-month';
|
||||
|
||||
export const sharedProps = {
|
||||
...pickerProps,
|
||||
filter: Function,
|
||||
modelValue: null,
|
||||
columnsOrder: Array,
|
||||
filter: Function as PropType<(type: string, values: string[]) => string[]>,
|
||||
columnsOrder: Array as PropType<ColumnType[]>,
|
||||
formatter: {
|
||||
type: Function,
|
||||
default: (type: string, value: unknown) => value,
|
||||
type: Function as PropType<(type: string, value: string) => string>,
|
||||
default: (type: string, value: string) => value,
|
||||
},
|
||||
};
|
||||
|
||||
export function times(n: number, iteratee: (index: number) => any[]) {
|
||||
export const pickerKeys = Object.keys(pickerProps) as Array<
|
||||
keyof typeof pickerProps
|
||||
>;
|
||||
|
||||
export function times<T>(n: number, iteratee: (index: number) => T) {
|
||||
let index = -1;
|
||||
const result = Array(n);
|
||||
const result: T[] = Array(n);
|
||||
|
||||
while (++index < n) {
|
||||
result[index] = iteratee(index);
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { isNaN } from './number';
|
||||
|
||||
export function isDate(val: Date): val is Date {
|
||||
export function isDate(val: unknown): val is Date {
|
||||
return (
|
||||
Object.prototype.toString.call(val) === '[object Date]' &&
|
||||
!isNaN(val.getTime())
|
||||
!isNaN((val as Date).getTime())
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user