From b9bca6a731ddbc2dae439acc618b0fc63cfa4b92 Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 19 Jun 2021 11:24:05 +0800 Subject: [PATCH] fix(Slider): format v-model with step correctly (#8893) --- src/slider/Slider.tsx | 12 +++++++++--- src/slider/test/index.spec.ts | 18 +++++++++++++++++- src/stepper/Stepper.tsx | 11 +++-------- src/utils/format/number.ts | 6 ++++++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/slider/Slider.tsx b/src/slider/Slider.tsx index a35dba55c..bbf5db15a 100644 --- a/src/slider/Slider.tsx +++ b/src/slider/Slider.tsx @@ -2,7 +2,9 @@ import { ref, computed, PropType, CSSProperties, defineComponent } from 'vue'; // Utils import { + range, addUnit, + addNumber, getSizeStyle, preventDefault, stopPropagation, @@ -102,9 +104,13 @@ export default defineComponent({ }); const format = (value: number) => { - const { min, max, step } = props; - value = Math.max(+min, Math.min(value, +max)); - return Math.round(value / +step) * +step; + const min = +props.min; + const max = +props.max; + const step = +props.step; + + value = range(value, min, max); + const diff = Math.round((value - min) / step) * step; + return addNumber(min, diff); }; const isSameValue = (newValue: SliderValue, oldValue: SliderValue) => diff --git a/src/slider/test/index.spec.ts b/src/slider/test/index.spec.ts index 2002ed048..350760be7 100644 --- a/src/slider/test/index.spec.ts +++ b/src/slider/test/index.spec.ts @@ -1,5 +1,6 @@ import { Slider } from '..'; import { + later, mount, trigger, triggerDrag, @@ -144,7 +145,7 @@ test('should change slider bar height when using bar-height prop', () => { expect(wrapper.style.height).toEqual('10px'); }); -test('shoud change button size when using button-size prop', () => { +test('should change button size when using button-size prop', () => { const wrapper = mount(Slider, { props: { modelValue: 50, @@ -187,3 +188,18 @@ test('should not emit change event when value not changed', async () => { expect(wrapper.emitted('change')!.length).toEqual(1); }); + +// https://github.com/youzan/vant/issues/8889 +test('should format v-model with step correctly', async () => { + const wrapper = mount(Slider, { + props: { + min: 29, + max: 39, + step: 2, + modelValue: 30.5, + }, + }); + + await later(); + expect(wrapper.emitted('update:modelValue')![0]).toEqual([31]); +}); diff --git a/src/stepper/Stepper.tsx b/src/stepper/Stepper.tsx index 05f100954..62b8b0edf 100644 --- a/src/stepper/Stepper.tsx +++ b/src/stepper/Stepper.tsx @@ -4,6 +4,7 @@ import { ref, watch, computed, PropType, defineComponent, nextTick } from 'vue'; import { isDef, addUnit, + addNumber, truthProp, resetScroll, formatNumber, @@ -25,12 +26,6 @@ function equal(value1?: string | number, value2?: string | number) { return String(value1) === String(value2); } -// add num and avoid float number -function add(num1: number, num2: number) { - const cardinal = 10 ** 10; - return Math.round((num1 + num2) * cardinal) / cardinal; -} - export type StepperTheme = 'default' | 'round'; export default defineComponent({ @@ -168,7 +163,7 @@ export default defineComponent({ } const diff = actionType === 'minus' ? -props.step : +props.step; - const value = format(add(+current.value, diff)); + const value = format(addNumber(+current.value, diff)); setValue(value); emit(actionType); @@ -215,7 +210,7 @@ export default defineComponent({ nextTick(() => { emit('blur', event); resetScroll(); - }) + }); }; let isLongPress: boolean; diff --git a/src/utils/format/number.ts b/src/utils/format/number.ts index 79317a359..b80503715 100644 --- a/src/utils/format/number.ts +++ b/src/utils/format/number.ts @@ -37,3 +37,9 @@ export function formatNumber( return value.replace(regExp, ''); } + +// add num and avoid float number +export function addNumber(num1: number, num2: number) { + const cardinal = 10 ** 10; + return Math.round((num1 + num2) * cardinal) / cardinal; +}