mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-05 19:41:42 +08:00
feat(Picker): add scroll-into event (#11757)
This commit is contained in:
parent
9e1640180b
commit
5e4bbab00c
@ -83,7 +83,14 @@ export default defineComponent({
|
||||
|
||||
props: pickerProps,
|
||||
|
||||
emits: ['confirm', 'cancel', 'change', 'clickOption', 'update:modelValue'],
|
||||
emits: [
|
||||
'confirm',
|
||||
'cancel',
|
||||
'change',
|
||||
'scrollInto',
|
||||
'clickOption',
|
||||
'update:modelValue',
|
||||
],
|
||||
|
||||
setup(props, { emit, slots }) {
|
||||
const columnsRef = ref<HTMLElement>();
|
||||
@ -165,11 +172,14 @@ export default defineComponent({
|
||||
});
|
||||
};
|
||||
|
||||
const onClickOption = (currentOption: PickerOption, columnIndex: number) =>
|
||||
emit(
|
||||
'clickOption',
|
||||
extend({ columnIndex, currentOption }, getEventParams())
|
||||
);
|
||||
const onClickOption = (
|
||||
currentOption: PickerOption,
|
||||
columnIndex: number
|
||||
) => {
|
||||
const params = { columnIndex, currentOption };
|
||||
emit('clickOption', extend(getEventParams(), params));
|
||||
emit('scrollInto', params);
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
children.forEach((child) => child.stopMomentum());
|
||||
@ -202,6 +212,12 @@ export default defineComponent({
|
||||
onClickOption={(option: PickerOption) =>
|
||||
onClickOption(option, columnIndex)
|
||||
}
|
||||
onScrollInto={(option: PickerOption) => {
|
||||
emit('scrollInto', {
|
||||
currentOption: option,
|
||||
columnIndex,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
));
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
watchEffect,
|
||||
defineComponent,
|
||||
type PropType,
|
||||
@ -56,7 +57,7 @@ export default defineComponent({
|
||||
visibleOptionNum: makeRequiredProp(numericProp),
|
||||
},
|
||||
|
||||
emits: ['change', 'clickOption'],
|
||||
emits: ['change', 'clickOption', 'scrollInto'],
|
||||
|
||||
setup(props, { emit, slots }) {
|
||||
let moving: boolean;
|
||||
@ -113,6 +114,8 @@ export default defineComponent({
|
||||
const getIndexByOffset = (offset: number) =>
|
||||
clamp(Math.round(-offset / props.optionHeight), 0, count() - 1);
|
||||
|
||||
const currentIndex = computed(() => getIndexByOffset(currentOffset.value));
|
||||
|
||||
const momentum = (distance: number, duration: number) => {
|
||||
const speed = Math.abs(distance / duration);
|
||||
|
||||
@ -166,16 +169,23 @@ export default defineComponent({
|
||||
preventDefault(event, true);
|
||||
}
|
||||
|
||||
currentOffset.value = clamp(
|
||||
const newOffset = clamp(
|
||||
startOffset + touch.deltaY.value,
|
||||
-(count() * props.optionHeight),
|
||||
props.optionHeight
|
||||
);
|
||||
|
||||
const newIndex = getIndexByOffset(newOffset);
|
||||
if (newIndex !== currentIndex.value) {
|
||||
emit('scrollInto', props.options[newIndex]);
|
||||
}
|
||||
|
||||
currentOffset.value = newOffset;
|
||||
|
||||
const now = Date.now();
|
||||
if (now - touchStartTime > MOMENTUM_TIME) {
|
||||
touchStartTime = now;
|
||||
momentumOffset = currentOffset.value;
|
||||
momentumOffset = newOffset;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -357,8 +357,9 @@ export default {
|
||||
| --- | --- | --- |
|
||||
| confirm | Emitted when the confirm button is clicked | _{ selectedValues, selectedOptions, selectedIndexes }_ |
|
||||
| cancel | Emitted when the cancel button is clicked | _{ selectedValues, selectedOptions, selectedIndexes }_ |
|
||||
| change | Emitted when current option is changed | _{ selectedValues, selectedOptions,selectedIndexes, columnIndex }_ |
|
||||
| change | Emitted when current selected option is changed | _{ selectedValues, selectedOptions,selectedIndexes, columnIndex }_ |
|
||||
| click-option | Emitted when an option is clicked | _{ currentOption, selectedValues, selectedOptions, selectedIndexes, columnIndex }_ |
|
||||
| scroll-into `v4.2.1` | Emitted when an option is scrolled into the middle selection area by clicking or dragging | _{ currentOption, columnIndex }_ |
|
||||
|
||||
### Slots
|
||||
|
||||
|
@ -378,8 +378,9 @@ export default {
|
||||
| --- | --- | --- |
|
||||
| confirm | 点击完成按钮时触发 | _{ selectedValues, selectedOptions, selectedIndexes }_ |
|
||||
| cancel | 点击取消按钮时触发 | _{ selectedValues, selectedOptions, selectedIndexes }_ |
|
||||
| change | 选项改变时触发 | _{ selectedValues, selectedOptions, selectedIndexes, columnIndex }_ |
|
||||
| change | 选中的选项改变时触发 | _{ selectedValues, selectedOptions, selectedIndexes, columnIndex }_ |
|
||||
| click-option | 点击选项时触发 | _{ currentOption, selectedValues, selectedOptions, selectedIndexes, columnIndex }_ |
|
||||
| scroll-into `v4.2.1` | 当用户通过点击或拖拽让一个选项滚动到中间的选择区域时触发 | _{ currentOption, columnIndex }_ |
|
||||
|
||||
### Slots
|
||||
|
||||
|
@ -143,6 +143,38 @@ test('should emit click-option event after clicking an option', async () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test('should emit scroll-into event after draging the column', async () => {
|
||||
const wrapper = mount(Picker, {
|
||||
props: {
|
||||
columns: simpleColumn,
|
||||
},
|
||||
});
|
||||
|
||||
triggerDrag(wrapper.find('.van-picker-column'), 0, -100);
|
||||
await wrapper.find('.van-picker-column ul').trigger('transitionend');
|
||||
|
||||
expect(wrapper.emitted('scrollInto')).toEqual([
|
||||
[{ columnIndex: 0, currentOption: { text: '1992', value: '1992' } }],
|
||||
]);
|
||||
});
|
||||
|
||||
test('should emit scroll-into event after clicking an option', async () => {
|
||||
const wrapper = mount(Picker, {
|
||||
props: {
|
||||
showToolbar: true,
|
||||
columns: simpleColumn,
|
||||
},
|
||||
});
|
||||
|
||||
await wrapper.find('.van-picker-column__item').trigger('click');
|
||||
expect(wrapper.emitted('scrollInto')![0]).toEqual([
|
||||
{
|
||||
columnIndex: 0,
|
||||
currentOption: { text: '1990', value: '1990' },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('should render bottom toolbar when toolbar-position is bottom', () => {
|
||||
const wrapper = mount(Picker, {
|
||||
props: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user