diff --git a/packages/vant/src/datetime-picker/DatePicker.tsx b/packages/vant/src/datetime-picker/DatePicker.tsx
index 621cec848..3bebf8809 100644
--- a/packages/vant/src/datetime-picker/DatePicker.tsx
+++ b/packages/vant/src/datetime-picker/DatePicker.tsx
@@ -23,6 +23,7 @@ import {
getTrueValue,
getMonthEndDay,
pickerInheritKeys,
+ proxyPickerMethods,
} from './utils';
// Composables
@@ -316,7 +317,8 @@ export default defineComponent({
);
useExpose({
- getPicker: () => picker.value,
+ getPicker: () =>
+ picker.value && proxyPickerMethods(picker.value, updateInnerValue),
});
return () => (
diff --git a/packages/vant/src/datetime-picker/TimePicker.tsx b/packages/vant/src/datetime-picker/TimePicker.tsx
index d3ecf692c..aac16aec1 100644
--- a/packages/vant/src/datetime-picker/TimePicker.tsx
+++ b/packages/vant/src/datetime-picker/TimePicker.tsx
@@ -16,7 +16,12 @@ import {
createNamespace,
makeNumericProp,
} from '../utils';
-import { times, sharedProps, pickerInheritKeys } from './utils';
+import {
+ times,
+ sharedProps,
+ pickerInheritKeys,
+ proxyPickerMethods,
+} from './utils';
// Composables
import { useExpose } from '../composables/use-expose';
@@ -160,7 +165,8 @@ export default defineComponent({
);
useExpose({
- getPicker: () => picker.value,
+ getPicker: () =>
+ picker.value && proxyPickerMethods(picker.value, updateInnerValue),
});
return () => (
diff --git a/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap b/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap
index 3b614dcc8..c69cff11f 100644
--- a/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap
+++ b/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap
@@ -1,22 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render title slot correctly 1`] = `
-
`;
+
+exports[`should render title slot correctly 1`] = `
+
+
+ Custom title
+
+
+`;
diff --git a/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx b/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx
index 929b4931c..76c0978b5 100644
--- a/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx
+++ b/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx
@@ -3,25 +3,29 @@ import { mount, later } from '../../../test';
import { reactive } from 'vue';
import { useExpose } from '../../composables/use-expose';
-test('confirm & cancel event', () => {
+test('should emit confirm event after clicking the confirm button', () => {
const onConfirm = jest.fn();
- const onCancel = jest.fn();
-
const wrapper = mount(DatetimePicker, {
props: {
onConfirm,
+ },
+ });
+ wrapper.find('.van-picker__confirm').trigger('click');
+ expect(onConfirm).toHaveBeenCalledTimes(1);
+});
+
+test('should emit cancel event after clicking the confirm button', () => {
+ const onCancel = jest.fn();
+ const wrapper = mount(DatetimePicker, {
+ props: {
onCancel,
},
});
-
- wrapper.find('.van-picker__confirm').trigger('click');
- expect(onConfirm).toHaveBeenCalledTimes(1);
-
wrapper.find('.van-picker__cancel').trigger('click');
expect(onCancel).toHaveBeenCalledTimes(1);
});
-test('time type', () => {
+test('should render time type correctly', () => {
const wrapper = mount(DatetimePicker, {
props: {
type: 'time',
@@ -33,7 +37,7 @@ test('time type', () => {
expect(wrapper.html()).toMatchSnapshot();
});
-test('getPicker method', () => {
+test('should allow to call getPicker method', () => {
const wrapper = mount(DatetimePicker);
expect(wrapper.vm.getPicker()).toBeTruthy();
@@ -86,3 +90,39 @@ test('should emit value correctly when dynamic change min-date', async () => {
wrapper.find('.van-picker__confirm').trigger('click');
expect(wrapper.emitted<[Date]>('confirm')![0][0]).toEqual(defaultValue);
});
+
+test('should update value correctly after calling setColumnIndex method', async () => {
+ const onConfirm = jest.fn();
+ const defaultDate = new Date(2020, 0, 1);
+ const wrapper = mount(DatetimePicker, {
+ props: {
+ type: 'date',
+ minDate: defaultDate,
+ maxDate: new Date(2020, 0, 30),
+ modelValue: defaultDate,
+ onConfirm,
+ },
+ });
+
+ wrapper.vm.getPicker().setColumnIndex(2, 14);
+ await wrapper.find('.van-picker__confirm').trigger('click');
+ expect(onConfirm.mock.calls[0]).toEqual([new Date(2020, 0, 15)]);
+});
+
+test('should update value correctly after calling setColumnValue method', async () => {
+ const onConfirm = jest.fn();
+ const defaultDate = new Date(2020, 0, 1);
+ const wrapper = mount(DatetimePicker, {
+ props: {
+ type: 'date',
+ minDate: defaultDate,
+ maxDate: new Date(2020, 0, 30),
+ modelValue: defaultDate,
+ onConfirm,
+ },
+ });
+
+ wrapper.vm.getPicker().setColumnValue(2, '15');
+ await wrapper.find('.van-picker__confirm').trigger('click');
+ expect(onConfirm.mock.calls[0]).toEqual([new Date(2020, 0, 15)]);
+});
diff --git a/packages/vant/src/datetime-picker/utils.ts b/packages/vant/src/datetime-picker/utils.ts
index ee09f1387..f78e90d06 100644
--- a/packages/vant/src/datetime-picker/utils.ts
+++ b/packages/vant/src/datetime-picker/utils.ts
@@ -1,6 +1,7 @@
import { PropType } from 'vue';
import { extend } from '../utils';
import { pickerSharedProps } from '../picker/Picker';
+import type { PickerInstance } from '../picker';
import type { DatetimePickerColumnType } from './types';
export const sharedProps = extend({}, pickerSharedProps, {
@@ -45,3 +46,27 @@ export function getTrueValue(value: string | undefined): number {
export const getMonthEndDay = (year: number, month: number): number =>
32 - new Date(year, month - 1, 32).getDate();
+
+// https://github.com/youzan/vant/issues/10013
+export const proxyPickerMethods = (
+ picker: PickerInstance,
+ callback: () => void
+) => {
+ const methods = [
+ 'setValues',
+ 'setIndexes',
+ 'setColumnIndex',
+ 'setColumnValue',
+ ];
+ return new Proxy(picker, {
+ get: (target, prop: keyof PickerInstance) => {
+ if (methods.includes(prop)) {
+ return (...args: unknown[]) => {
+ target[prop](...args);
+ callback();
+ };
+ }
+ return target[prop];
+ },
+ });
+};