From ef8e66a9244606899339c7153ec2d66406afbf81 Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Tue, 15 Feb 2022 15:42:23 +0800 Subject: [PATCH] refactor(DatePicker): v-model now is string array --- packages/vant/src/date-picker/DatePicker.tsx | 80 +++++++------------ packages/vant/src/date-picker/README.md | 9 ++- packages/vant/src/date-picker/README.zh-CN.md | 9 ++- packages/vant/src/date-picker/demo/index.vue | 8 +- packages/vant/src/slider/Slider.tsx | 4 +- packages/vant/src/utils/basic.ts | 3 + 6 files changed, 47 insertions(+), 66 deletions(-) diff --git a/packages/vant/src/date-picker/DatePicker.tsx b/packages/vant/src/date-picker/DatePicker.tsx index 55c94c0ff..d77dde992 100644 --- a/packages/vant/src/date-picker/DatePicker.tsx +++ b/packages/vant/src/date-picker/DatePicker.tsx @@ -1,5 +1,6 @@ import { ref, + watch, computed, defineComponent, type PropType, @@ -9,10 +10,11 @@ import { // Utils import { pick, - clamp, extend, isDate, padZero, + isSameValue, + makeArrayProp, createNamespace, } from '../utils'; import { @@ -31,7 +33,7 @@ const [name] = createNamespace('date-picker'); export type DatePickerColumnType = 'year' | 'month' | 'day'; const datePickerProps = extend({}, sharedProps, { - modelValue: Date, + modelValue: makeArrayProp(), columnsType: { type: Array as PropType, default: () => ['year', 'month', 'day'], @@ -58,42 +60,7 @@ export default defineComponent({ emits: ['confirm', 'cancel', 'change', 'update:modelValue'], setup(props, { emit, slots }) { - const currentValues = ref([]); - - // 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 formatValue = (value: Date) => { - const timestamp = clamp( - value.getTime(), - props.minDate.getTime(), - props.maxDate.getTime() - ); - - const date = new Date(timestamp); - return props.columnsType.map((type) => { - switch (type) { - case 'year': - return String(date.getFullYear()); - case 'month': - return padZero(date.getMonth() + 1); - case 'day': - default: - return padZero(date.getDate()); - } - }); - }; - - if (props.modelValue) { - currentValues.value = formatValue(props.modelValue); - } + const currentValues = ref(props.modelValue); const genOptions = ( min: number, @@ -120,6 +87,11 @@ export default defineComponent({ const isMaxMonth = (month: number) => month === props.maxDate.getMonth() + 1; + const getValue = (type: DatePickerColumnType) => { + const index = props.columnsType.indexOf(type); + return +currentValues.value[index]; + }; + const genMonthOptions = () => { if (isMaxYear(getValue('year'))) { return genOptions(1, props.maxDate.getMonth() + 1, 'month'); @@ -156,20 +128,26 @@ export default defineComponent({ }) ); - // watch(currentValues, (value, oldValue) => - // emit('update:modelValue', oldValue ? value : null) - // ); + watch( + currentValues, + (newValues) => { + if (isSameValue(newValues, props.modelValue)) { + emit('update:modelValue', newValues); + } + }, + { + deep: true, + } + ); - // watch( - // () => props.modelValue, - // (value) => { - // value = formatValue(value); - - // if (value && value.valueOf() !== currentValues.value?.valueOf()) { - // currentValues.value = value; - // } - // } - // ); + watch( + () => props.modelValue, + (newValues) => { + if (isSameValue(newValues, currentValues.value)) { + currentValues.value = newValues; + } + } + ); const onChange = (...args: unknown[]) => emit('change', ...args); const onCancel = (...args: unknown[]) => emit('cancel', ...args); diff --git a/packages/vant/src/date-picker/README.md b/packages/vant/src/date-picker/README.md index 63dc8491e..a89add262 100644 --- a/packages/vant/src/date-picker/README.md +++ b/packages/vant/src/date-picker/README.md @@ -29,7 +29,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); return { minDate: new Date(2020, 0, 1), maxDate: new Date(2025, 5, 1), @@ -65,7 +65,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); return { minDate: new Date(2020, 0, 1), maxDate: new Date(2025, 5, 1), @@ -93,7 +93,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); const formatter = (type, val) => { if (type === 'year') { @@ -133,7 +133,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); const filter = (type, options) => { if (type === 'month') { return options.filter((option) => Number(option.value) % 6 === 0); @@ -157,6 +157,7 @@ export default { | Attribute | Description | Type | Default | | --- | --- | --- | --- | +| v-model | Current date | _string[]_ | `[]` | | columns-type | Columns type | _string[]_ | `['year', 'month', 'day']` | | min-date | Min date | _Date_ | Ten years ago on January 1 | | max-date | Max date | _Date_ | Ten years later on December 31 | diff --git a/packages/vant/src/date-picker/README.zh-CN.md b/packages/vant/src/date-picker/README.zh-CN.md index 93e5b9caa..e6f9032d3 100644 --- a/packages/vant/src/date-picker/README.zh-CN.md +++ b/packages/vant/src/date-picker/README.zh-CN.md @@ -31,7 +31,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); return { minDate: new Date(2020, 0, 1), maxDate: new Date(2025, 5, 1), @@ -67,7 +67,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); return { minDate: new Date(2020, 0, 1), maxDate: new Date(2025, 5, 1), @@ -97,7 +97,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); const formatter = (type, val) => { if (type === 'year') { @@ -139,7 +139,7 @@ import { ref } from 'vue'; export default { setup() { - const currentDate = ref(new Date(2021, 0, 1)); + const currentDate = ref(['2021', '01', '01']); const filter = (type, options) => { if (type === 'month') { return options.filter((option) => Number(option.value) % 6 === 0); @@ -163,6 +163,7 @@ export default { | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | +| v-model | 当前选中的日期 | _string[]_ | `[]` | | columns-type | 选项类型,由 `year`、`month` 和 `day` 组成的数组 | _string[]_ | `['year', 'month', 'day']` | | min-date | 可选的最小时间,精确到日 | _Date_ | 十年前 | | max-date | 可选的最大时间,精确到日 | _Date_ | 十年后 | diff --git a/packages/vant/src/date-picker/demo/index.vue b/packages/vant/src/date-picker/demo/index.vue index 230d27b5a..297f6d6d4 100644 --- a/packages/vant/src/date-picker/demo/index.vue +++ b/packages/vant/src/date-picker/demo/index.vue @@ -29,10 +29,10 @@ const t = useTranslate({ const minDate = new Date(2020, 0, 1); const maxDate = new Date(2025, 5, 1); -const basicDate = ref(new Date(2021, 0, 1)); -const yearMonthDate = ref(new Date(2021, 0, 1)); -const formatterDate = ref(new Date(2021, 0, 1)); -const filterDate = ref(new Date(2021, 0, 1)); +const basicDate = ref(['2021', '01', '01']); +const yearMonthDate = ref(['2021', '01', '01']); +const formatterDate = ref(['2021', '01', '01']); +const filterDate = ref(['2021', '01', '01']); const filter = (type: string, options: PickerOption[]) => { if (type === 'month') { diff --git a/packages/vant/src/slider/Slider.tsx b/packages/vant/src/slider/Slider.tsx index 2730e10cd..d8348abbc 100644 --- a/packages/vant/src/slider/Slider.tsx +++ b/packages/vant/src/slider/Slider.tsx @@ -13,6 +13,7 @@ import { addUnit, addNumber, numericProp, + isSameValue, getSizeStyle, preventDefault, stopPropagation, @@ -131,9 +132,6 @@ export default defineComponent({ return addNumber(min, diff); }; - const isSameValue = (newValue: SliderValue, oldValue: SliderValue) => - JSON.stringify(newValue) === JSON.stringify(oldValue); - const handleRangeValue = (value: NumberRange) => { // 设置默认值 const left = value[0] ?? Number(props.min); diff --git a/packages/vant/src/utils/basic.ts b/packages/vant/src/utils/basic.ts index b96e89913..159b3ffb2 100644 --- a/packages/vant/src/utils/basic.ts +++ b/packages/vant/src/utils/basic.ts @@ -34,3 +34,6 @@ export function pick( return ret; }, {} as Writeable>); } + +export const isSameValue = (newValue: unknown, oldValue: unknown) => + JSON.stringify(newValue) === JSON.stringify(oldValue);