-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
fix(Field): sync input value when dynamically toggling input slot #13783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
30af04b
37fc0b8
72c750b
f7685da
c5b0ba9
3430626
be2e46d
c7fe1a6
13248f7
42d9458
5d85c3b
8137a85
5a48f52
d24b1e7
e37c8fe
91259b9
a3774da
288cd25
b5ee53a
06b35df
22ceb87
a7e2f52
bc40733
6bbbb14
08064d3
cb5f579
736f8b4
8810099
6cfc45d
b5a0091
5ef1075
0547793
3a39f04
ee47f30
6953c40
5dd6def
ef5c686
38ce3e7
fd9c90d
b7648e0
a03d1b3
9be4cbd
ca1e404
37f1d8a
aeadef6
f9a1d0d
f8c6668
835676e
e996104
9282a87
728aae9
e8c4b50
aa4f540
46318fe
7f7ce3f
a5e8351
a90cace
572efca
d0cafc7
8de91ac
c039ba7
ac685ee
9dcc149
ffa9237
a5f73ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -663,3 +663,44 @@ test('should limit maxlength correctly when pasting multiple emojis', async () = | |
| expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('1😀😀😀'); | ||
| expect(input.element.value).toEqual('1😀😀😀'); | ||
| }); | ||
|
|
||
| test('should sync value when dynamically toggling input slot', async () => { | ||
| const wrapper = mount({ | ||
| data() { | ||
| return { | ||
| useSlot: false, | ||
| modelValue: 'hello', | ||
| }; | ||
| }, | ||
| render() { | ||
| return ( | ||
| <Field | ||
| v-model={this.modelValue} | ||
| v-slots={{ | ||
| input: this.useSlot ? () => 'Custom Input' : undefined, | ||
| }} | ||
| /> | ||
| ); | ||
| }, | ||
| }); | ||
|
|
||
| let input = wrapper.find('input'); | ||
| expect(input.element.value).toEqual('hello'); | ||
|
|
||
| // Toggle to use custom input slot | ||
| await wrapper.vm.$data.useSlot = true; | ||
| await wrapper.vm.$nextTick(); | ||
| expect(wrapper.find('.van-field__control').text()).toContain('Custom Input'); | ||
|
|
||
| // Update model value while slot is active | ||
| await wrapper.vm.$data.modelValue = 'world'; | ||
| await wrapper.vm.$nextTick(); | ||
|
|
||
| // Toggle back to native input | ||
| await wrapper.vm.$data.useSlot = false; | ||
| await wrapper.vm.$nextTick(); | ||
|
|
||
| // The native input should have the updated value | ||
| input = wrapper.find('input'); | ||
| expect(input.element.value).toEqual('world'); | ||
| }); | ||
|
Comment on lines
+667
to
+706
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,8 +129,18 @@ export default defineComponent({ | |
| const step = +props.step; | ||
|
|
||
| value = clamp(value, min, max); | ||
|
|
||
| const diff = Math.round((value - min) / step) * step; | ||
| return addNumber(min, diff); | ||
| const steppedValue = addNumber(min, diff); | ||
|
|
||
| if (steppedValue > max) { | ||
| const prevSteppedValue = addNumber(min, diff - step); | ||
| const distanceToMax = Math.abs(value - max); | ||
| const distanceToPrev = Math.abs(value - prevSteppedValue); | ||
|
|
||
| return distanceToMax <= distanceToPrev ? max : prevSteppedValue; | ||
| } | ||
| return steppedValue; | ||
|
Comment on lines
+132
to
+143
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }; | ||
|
|
||
| const updateStartValue = () => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -374,3 +374,31 @@ test('should update modelValue correctly after clicking the reversed vertical sl | |
| trigger(wrapper, 'click', 0, 100); | ||
| expect(wrapper.emitted('update:modelValue')!.pop()).toEqual([0]); | ||
| }); | ||
|
|
||
| //https://github.com/youzan/vant/issues/13625 | ||
| test('should return max when distanceToMax <= distanceToPrev', () => { | ||
| const wrapper = mount(Slider, { | ||
| props: { min: 0, max: 50, step: 60, modelValue: 45 }, | ||
| }); | ||
|
|
||
| const emitted = wrapper.emitted('update:modelValue'); | ||
| if (emitted && emitted.length > 0) { | ||
| const result = emitted[emitted.length - 1][0] as number; | ||
| expect(result).toBe(50); // Should return max | ||
| } | ||
|
Comment on lines
+378
to
+388
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }); | ||
|
|
||
| test('should enter steppedValue > max branch', () => { | ||
| const wrapper = mount(Slider, { | ||
| props: { min: 0, max: 12, step: 20, modelValue: 0 }, | ||
| }); | ||
|
|
||
| wrapper.setProps({ modelValue: 11 }); | ||
|
|
||
| const emitted = wrapper.emitted('update:modelValue'); | ||
| if (emitted && emitted.length > 0) { | ||
| const result = emitted[emitted.length - 1][0] as number; | ||
| expect(result).toBeGreaterThanOrEqual(0); | ||
| expect(result).toBeLessThanOrEqual(12); | ||
| } | ||
|
Comment on lines
+391
to
+403
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new watcher correctly addresses the issue of syncing the input value when the input element is recreated due to dynamic slot toggling. This is a good solution to ensure data consistency.