diff --git a/packages/vant/src/picker/PickerColumn.tsx b/packages/vant/src/picker/PickerColumn.tsx index 42357a75b..e36314baf 100644 --- a/packages/vant/src/picker/PickerColumn.tsx +++ b/packages/vant/src/picker/PickerColumn.tsx @@ -78,10 +78,14 @@ export default defineComponent({ (props.optionHeight * (+props.visibleOptionNum - 1)) / 2; const updateValueByIndex = (index: number) => { - const enabledIndex = findIndexOfEnabledOption(props.options, index); + let enabledIndex = findIndexOfEnabledOption(props.options, index); const offset = -enabledIndex * props.optionHeight; const trigger = () => { + if (enabledIndex > count() - 1) { + enabledIndex = findIndexOfEnabledOption(props.options, index); + } + const value = props.options[enabledIndex][props.fields.value]; if (value !== props.value) { emit('change', value); @@ -259,11 +263,14 @@ export default defineComponent({ useExpose({ stopMomentum }); watchEffect(() => { - const index = props.options.findIndex( - (option) => option[props.fields.value] === props.value - ); + const index = moving + ? Math.floor(-currentOffset.value / props.optionHeight) + : props.options.findIndex( + (option) => option[props.fields.value] === props.value + ); const enabledIndex = findIndexOfEnabledOption(props.options, index); const offset = -enabledIndex * props.optionHeight; + if (moving && enabledIndex < index) stopMomentum(); currentOffset.value = offset; }); diff --git a/packages/vant/src/picker/test/index.spec.tsx b/packages/vant/src/picker/test/index.spec.tsx index f147d7fc1..e84bf1870 100644 --- a/packages/vant/src/picker/test/index.spec.tsx +++ b/packages/vant/src/picker/test/index.spec.tsx @@ -46,6 +46,33 @@ test('should emit cancel event after clicking the cancel button', () => { ]); }); +test('should work correctly when dragging the column and changing columns prop', async () => { + const columnsOne = [ + { text: '1990', value: '1990' }, + { text: '1991', value: '1991' }, + ]; + const columnsTwo = [{ text: '1993', value: '1993' }]; + const wrapper = mount(Picker, { + props: { + columns: columnsOne, + }, + }); + + triggerDrag(wrapper.findAll('.van-picker-column')[0], 0, -100); + await wrapper.setProps({ + columns: columnsTwo, + }); + await wrapper.find('.van-picker__confirm').trigger('click'); + + expect(wrapper.emitted<[string, number]>('confirm')![0]).toEqual([ + { + selectedOptions: [{ text: '1993', value: '1993' }], + selectedValues: ['1993'], + selectedIndexes: [0], + }, + ]); +}); + test('should emit change event after draging the column', async () => { const wrapper = mount(Picker, { props: {