From 3bb0f0ff1275a05dc7b7550a80f85428f6c32788 Mon Sep 17 00:00:00 2001 From: yoyo <15014217605@163.com> Date: Fri, 8 Dec 2023 16:29:04 +0800 Subject: [PATCH] fix(slider): [slider] value of input does not change when using max and min (#1056) --- .../demos/pc/app/slider/webdoc/slider.js | 41 +++++++++++-------- packages/renderless/src/slider/index.ts | 18 ++++++++ packages/renderless/src/slider/vue.ts | 19 +++++++-- packages/renderless/types/slider.type.ts | 7 ++++ packages/vue/src/slider/src/pc.vue | 9 +++- 5 files changed, 71 insertions(+), 23 deletions(-) diff --git a/examples/sites/demos/pc/app/slider/webdoc/slider.js b/examples/sites/demos/pc/app/slider/webdoc/slider.js index 44006039c..34df1a49b 100644 --- a/examples/sites/demos/pc/app/slider/webdoc/slider.js +++ b/examples/sites/demos/pc/app/slider/webdoc/slider.js @@ -59,7 +59,8 @@ export default { 'demoId': 'shortcut-operation', 'name': { 'zh-CN': '快捷键操作', 'en-US': 'Shortcut Key Operations' }, 'desc': { - 'zh-CN': '

通过设置num-pages总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"。

', + 'zh-CN': + '

通过设置num-pages总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"。

', 'en-US': '

Set num-pagesthe total number of steps. That is, when you press the shortcut key PageDown or PageUp, the moving distance is "⌈(max-min)/num-pages⌉"。

' }, @@ -104,7 +105,7 @@ export default { 'name': { 'zh-CN': '事件', 'en-US': 'Event' }, 'desc': { 'zh-CN': '

change、start、stop 事件。

', 'en-US': '

change, start, stop events.

' }, 'codeFiles': ['slider-event.vue'] - }, + } ], apis: [ { @@ -114,7 +115,10 @@ export default { { 'name': 'v-model', 'type': 'number | [number, number]', - 'desc': { 'zh-CN': '设置单滑块的当前值,必需是整数或数组', 'en-US': 'Sets the current value of a single slider. The value must be an integer or an array.' }, + 'desc': { + 'zh-CN': '设置单滑块的当前值,必需是整数或数组', + 'en-US': 'Sets the current value of a single slider. The value must be an integer or an array.' + }, 'demoId': 'basic-usage' }, { @@ -180,7 +184,10 @@ export default { 'name': 'height', 'type': 'string', 'defaultValue': `'300px'`, - 'desc': { 'zh-CN': 'Slider组件的高度,当vertical为true时有效', 'en-US': 'Height of Slider component, effective when vertical is true' }, + 'desc': { + 'zh-CN': 'Slider 组件的高度,当 vertical 为 true 时有效', + 'en-US': 'Height of Slider component, effective when vertical is true' + }, 'demoId': 'vertical-mode' }, { @@ -188,8 +195,7 @@ export default { 'type': 'number', 'defaultValue': '1', 'desc': { - 'zh-CN': - '设置总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"', + 'zh-CN': '设置总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"', 'en-US': 'Set the total number of steps. That is, when you press PageDown or PageUp, the moving distance is "⌈(max-min)/num-pages⌉".' }, @@ -209,8 +215,7 @@ export default { 'type': '(value: number | [number, number]) => void', 'defaultValue': '', 'desc': { - 'zh-CN': - '值改变时触发(使用鼠标拖曳时,只在松开鼠标后触发)', + 'zh-CN': '值改变时触发(使用鼠标拖曳时,只在松开鼠标后触发)', 'en-US': 'Triggered when the value changes (When you drag the mouse, it is triggered only after you release the mouse).' }, @@ -221,22 +226,18 @@ export default { 'type': '(event: Event, value: number | [number, number]) => void', 'defaultValue': '', 'desc': { - 'zh-CN': - '设置滑块滑动开始时,触发该事件', - 'en-US': - 'This event is triggered when the slider starts to slide.' + 'zh-CN': '设置滑块滑动开始时,触发该事件', + 'en-US': 'This event is triggered when the slider starts to slide.' }, 'demoId': 'slider-event' }, { - 'name': 'Stop', + 'name': 'stop', 'type': '(value: number | [number, number]) => void', 'defaultValue': '', 'desc': { - 'zh-CN': - '设置滑块滑动结束时,触发该事件', - 'en-US': - 'This event is triggered when the slider sliding ends. ' + 'zh-CN': '设置滑块滑动结束时,触发该事件', + 'en-US': 'This event is triggered when the slider sliding ends. ' }, 'demoId': 'slider-event' } @@ -246,7 +247,11 @@ export default { 'name': 'default', 'type': '', 'defaultValue': '', - 'desc': { 'zh-CN': '显示滑块值的插槽,仅仅v-model是单数值时才有效,插槽参数为:slotArg: { slotScope: number }', 'en-US': 'Slot for displaying slider values, valid only if v-model is a single value. Slot parameters are: slotArg: {slotScope: number}' }, + 'desc': { + 'zh-CN': '显示滑块值的插槽,仅仅 v-model 是单数值时才有效,插槽参数为:slotArg: { slotScope: number }', + 'en-US': + 'Slot for displaying slider values, valid only if v-model is a single value. Slot parameters are: slotArg: {slotScope: number}' + }, 'demoId': 'slider-slot' } ] diff --git a/packages/renderless/src/slider/index.ts b/packages/renderless/src/slider/index.ts index 08329dcc0..2bed372c0 100644 --- a/packages/renderless/src/slider/index.ts +++ b/packages/renderless/src/slider/index.ts @@ -483,6 +483,11 @@ export const watchActiveValue = } else { state.activeValue = nNewValue || 0 } + + // 正在输入时,不应该改变输入的内容 + if (!state.isSlotTyping) { + state.slotValue = state.activeValue + } } export const watchModelValue = @@ -554,3 +559,16 @@ export const inputValueChange = } api.initSlider([Math.min(...state.inputValue), Math.max(...state.inputValue)]) } + +export const handleSlotInputFocus = (state: ISliderRenderlessParams['state']) => () => { + state.isSlotTyping = true +} + +export const handleSlotInputBlur = (state: ISliderRenderlessParams['state']) => () => { + state.isSlotTyping = false + state.slotValue = state.activeValue +} + +export const handleSlotInput = (state: ISliderRenderlessParams['state']) => (event: Event) => { + state.activeValue = Number((event.target as HTMLInputElement).value) +} diff --git a/packages/renderless/src/slider/vue.ts b/packages/renderless/src/slider/vue.ts index abf11711a..eedff74ab 100644 --- a/packages/renderless/src/slider/vue.ts +++ b/packages/renderless/src/slider/vue.ts @@ -38,7 +38,10 @@ import { watchModelValue, getPoints, getLabels, - inputValueChange + inputValueChange, + handleSlotInputFocus, + handleSlotInputBlur, + handleSlotInput } from './index' import type { @@ -74,7 +77,10 @@ export const api = [ 'customBeforeAppearHook', 'customAppearHook', 'customAfterAppearHook', - 'inputValueChange' + 'inputValueChange', + 'handleSlotInputFocus', + 'handleSlotInputBlur', + 'handleSlotInput' ] const initState = ({ reactive, computed, props, api, parent, inject }) => { @@ -106,7 +112,9 @@ const initState = ({ reactive, computed, props, api, parent, inject }) => { rangeDiff: computed(() => props.max - props.min), tipValue: computed(() => api.formatTipValue(state.activeValue)), formDisabled: computed(() => (parent.tinyForm || {}).disabled), - disabled: computed(() => props.disabled || state.formDisabled) + disabled: computed(() => props.disabled || state.formDisabled), + slotValue: '', + isSlotTyping: false }) return state @@ -150,7 +158,10 @@ export const renderless = ( watchActiveValue: watchActiveValue({ api, emit, props, state }), getPoints: getPoints({ props, state }), getLabels: getLabels({ props, state }), - inputValueChange: inputValueChange({ props, api, state }) + inputValueChange: inputValueChange({ props, api, state }), + handleSlotInputFocus: handleSlotInputFocus(state), + handleSlotInputBlur: handleSlotInputBlur(state), + handleSlotInput: handleSlotInput(state) }) watch(() => props.modelValue, api.watchModelValue, { immediate: true }) diff --git a/packages/renderless/types/slider.type.ts b/packages/renderless/types/slider.type.ts index 21daccf93..055ac2497 100644 --- a/packages/renderless/types/slider.type.ts +++ b/packages/renderless/types/slider.type.ts @@ -34,6 +34,10 @@ export interface ISliderState { tipValue: ComputedRef formDisabled: ComputedRef disabled: ComputedRef + /** 使用这个值作为插槽中输入的值,而不是直接用activeValue,来实现在输入时不会被max min属性计算而改变 */ + slotValue: number + /** 是否正在输入 */ + isSlotTyping: boolean } export interface ISliderApi { @@ -65,6 +69,9 @@ export interface ISliderApi { getPoints: () => void getLabels: () => void inputValueChange: () => void + handleSlotInputFocus: () => void + handleSlotInputBlur: () => void + handleSlotInput: (event: Event) => void } export type ISliderRenderlessParams = ISharedRenderlessFunctionParams & { diff --git a/packages/vue/src/slider/src/pc.vue b/packages/vue/src/slider/src/pc.vue index 0e19b6ebb..fc0129fca 100644 --- a/packages/vue/src/slider/src/pc.vue +++ b/packages/vue/src/slider/src/pc.vue @@ -74,7 +74,14 @@