fix(slider): [slider] value of input does not change when using max and min (#1056)
This commit is contained in:
parent
2a2383b0bb
commit
3bb0f0ff12
|
@ -59,7 +59,8 @@ export default {
|
||||||
'demoId': 'shortcut-operation',
|
'demoId': 'shortcut-operation',
|
||||||
'name': { 'zh-CN': '快捷键操作', 'en-US': 'Shortcut Key Operations' },
|
'name': { 'zh-CN': '快捷键操作', 'en-US': 'Shortcut Key Operations' },
|
||||||
'desc': {
|
'desc': {
|
||||||
'zh-CN': '<p>通过设置<code>num-pages</code>总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"。</p>',
|
'zh-CN':
|
||||||
|
'<p>通过设置<code>num-pages</code>总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"。</p>',
|
||||||
'en-US':
|
'en-US':
|
||||||
'<p>Set <code>num-pages</code>the total number of steps. That is, when you press the shortcut key PageDown or PageUp, the moving distance is "⌈(max-min)/num-pages⌉"。</p>'
|
'<p>Set <code>num-pages</code>the total number of steps. That is, when you press the shortcut key PageDown or PageUp, the moving distance is "⌈(max-min)/num-pages⌉"。</p>'
|
||||||
},
|
},
|
||||||
|
@ -104,7 +105,7 @@ export default {
|
||||||
'name': { 'zh-CN': '事件', 'en-US': 'Event' },
|
'name': { 'zh-CN': '事件', 'en-US': 'Event' },
|
||||||
'desc': { 'zh-CN': '<p>change、start、stop 事件。</p>', 'en-US': '<p>change, start, stop events.</p>' },
|
'desc': { 'zh-CN': '<p>change、start、stop 事件。</p>', 'en-US': '<p>change, start, stop events.</p>' },
|
||||||
'codeFiles': ['slider-event.vue']
|
'codeFiles': ['slider-event.vue']
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
apis: [
|
apis: [
|
||||||
{
|
{
|
||||||
|
@ -114,7 +115,10 @@ export default {
|
||||||
{
|
{
|
||||||
'name': 'v-model',
|
'name': 'v-model',
|
||||||
'type': 'number | [number, number]',
|
'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'
|
'demoId': 'basic-usage'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -180,7 +184,10 @@ export default {
|
||||||
'name': 'height',
|
'name': 'height',
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'defaultValue': `'300px'`,
|
'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'
|
'demoId': 'vertical-mode'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -188,8 +195,7 @@ export default {
|
||||||
'type': 'number',
|
'type': 'number',
|
||||||
'defaultValue': '1',
|
'defaultValue': '1',
|
||||||
'desc': {
|
'desc': {
|
||||||
'zh-CN':
|
'zh-CN': '设置总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"',
|
||||||
'设置总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 "⌈(max-min)/num-pages⌉"',
|
|
||||||
'en-US':
|
'en-US':
|
||||||
'Set the total number of steps. That is, when you press PageDown or PageUp, the moving distance is "⌈(max-min)/num-pages⌉".'
|
'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',
|
'type': '(value: number | [number, number]) => void',
|
||||||
'defaultValue': '',
|
'defaultValue': '',
|
||||||
'desc': {
|
'desc': {
|
||||||
'zh-CN':
|
'zh-CN': '值改变时触发(使用鼠标拖曳时,只在松开鼠标后触发)',
|
||||||
'值改变时触发(使用鼠标拖曳时,只在松开鼠标后触发)',
|
|
||||||
'en-US':
|
'en-US':
|
||||||
'Triggered when the value changes (When you drag the mouse, it is triggered only after you release the mouse).'
|
'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',
|
'type': '(event: Event, value: number | [number, number]) => void',
|
||||||
'defaultValue': '',
|
'defaultValue': '',
|
||||||
'desc': {
|
'desc': {
|
||||||
'zh-CN':
|
'zh-CN': '设置滑块滑动开始时,触发该事件',
|
||||||
'设置滑块滑动开始时,触发该事件',
|
'en-US': 'This event is triggered when the slider starts to slide.'
|
||||||
'en-US':
|
|
||||||
'This event is triggered when the slider starts to slide.'
|
|
||||||
},
|
},
|
||||||
'demoId': 'slider-event'
|
'demoId': 'slider-event'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Stop',
|
'name': 'stop',
|
||||||
'type': '(value: number | [number, number]) => void',
|
'type': '(value: number | [number, number]) => void',
|
||||||
'defaultValue': '',
|
'defaultValue': '',
|
||||||
'desc': {
|
'desc': {
|
||||||
'zh-CN':
|
'zh-CN': '设置滑块滑动结束时,触发该事件',
|
||||||
'设置滑块滑动结束时,触发该事件',
|
'en-US': 'This event is triggered when the slider sliding ends. '
|
||||||
'en-US':
|
|
||||||
'This event is triggered when the slider sliding ends. '
|
|
||||||
},
|
},
|
||||||
'demoId': 'slider-event'
|
'demoId': 'slider-event'
|
||||||
}
|
}
|
||||||
|
@ -246,7 +247,11 @@ export default {
|
||||||
'name': 'default',
|
'name': 'default',
|
||||||
'type': '',
|
'type': '',
|
||||||
'defaultValue': '',
|
'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'
|
'demoId': 'slider-slot'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -483,6 +483,11 @@ export const watchActiveValue =
|
||||||
} else {
|
} else {
|
||||||
state.activeValue = nNewValue || 0
|
state.activeValue = nNewValue || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 正在输入时,不应该改变输入的内容
|
||||||
|
if (!state.isSlotTyping) {
|
||||||
|
state.slotValue = state.activeValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const watchModelValue =
|
export const watchModelValue =
|
||||||
|
@ -554,3 +559,16 @@ export const inputValueChange =
|
||||||
}
|
}
|
||||||
api.initSlider([Math.min(...state.inputValue), Math.max(...state.inputValue)])
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -38,7 +38,10 @@ import {
|
||||||
watchModelValue,
|
watchModelValue,
|
||||||
getPoints,
|
getPoints,
|
||||||
getLabels,
|
getLabels,
|
||||||
inputValueChange
|
inputValueChange,
|
||||||
|
handleSlotInputFocus,
|
||||||
|
handleSlotInputBlur,
|
||||||
|
handleSlotInput
|
||||||
} from './index'
|
} from './index'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
@ -74,7 +77,10 @@ export const api = [
|
||||||
'customBeforeAppearHook',
|
'customBeforeAppearHook',
|
||||||
'customAppearHook',
|
'customAppearHook',
|
||||||
'customAfterAppearHook',
|
'customAfterAppearHook',
|
||||||
'inputValueChange'
|
'inputValueChange',
|
||||||
|
'handleSlotInputFocus',
|
||||||
|
'handleSlotInputBlur',
|
||||||
|
'handleSlotInput'
|
||||||
]
|
]
|
||||||
|
|
||||||
const initState = ({ reactive, computed, props, api, parent, inject }) => {
|
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),
|
rangeDiff: computed(() => props.max - props.min),
|
||||||
tipValue: computed(() => api.formatTipValue(state.activeValue)),
|
tipValue: computed(() => api.formatTipValue(state.activeValue)),
|
||||||
formDisabled: computed(() => (parent.tinyForm || {}).disabled),
|
formDisabled: computed(() => (parent.tinyForm || {}).disabled),
|
||||||
disabled: computed(() => props.disabled || state.formDisabled)
|
disabled: computed(() => props.disabled || state.formDisabled),
|
||||||
|
slotValue: '',
|
||||||
|
isSlotTyping: false
|
||||||
})
|
})
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
@ -150,7 +158,10 @@ export const renderless = (
|
||||||
watchActiveValue: watchActiveValue({ api, emit, props, state }),
|
watchActiveValue: watchActiveValue({ api, emit, props, state }),
|
||||||
getPoints: getPoints({ props, state }),
|
getPoints: getPoints({ props, state }),
|
||||||
getLabels: getLabels({ 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 })
|
watch(() => props.modelValue, api.watchModelValue, { immediate: true })
|
||||||
|
|
|
@ -34,6 +34,10 @@ export interface ISliderState {
|
||||||
tipValue: ComputedRef<string>
|
tipValue: ComputedRef<string>
|
||||||
formDisabled: ComputedRef<boolean>
|
formDisabled: ComputedRef<boolean>
|
||||||
disabled: ComputedRef<boolean>
|
disabled: ComputedRef<boolean>
|
||||||
|
/** 使用这个值作为插槽中输入的值,而不是直接用activeValue,来实现在输入时不会被max min属性计算而改变 */
|
||||||
|
slotValue: number
|
||||||
|
/** 是否正在输入 */
|
||||||
|
isSlotTyping: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISliderApi {
|
export interface ISliderApi {
|
||||||
|
@ -65,6 +69,9 @@ export interface ISliderApi {
|
||||||
getPoints: () => void
|
getPoints: () => void
|
||||||
getLabels: () => void
|
getLabels: () => void
|
||||||
inputValueChange: () => void
|
inputValueChange: () => void
|
||||||
|
handleSlotInputFocus: () => void
|
||||||
|
handleSlotInputBlur: () => void
|
||||||
|
handleSlotInput: (event: Event) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ISliderRenderlessParams = ISharedRenderlessFunctionParams<ISliderConstants> & {
|
export type ISliderRenderlessParams = ISharedRenderlessFunctionParams<ISliderConstants> & {
|
||||||
|
|
|
@ -74,7 +74,14 @@
|
||||||
<template v-if="showInput && !state.isDouble">
|
<template v-if="showInput && !state.isDouble">
|
||||||
<div class="tiny-slider__input">
|
<div class="tiny-slider__input">
|
||||||
<slot :slot-scope="state.activeValue">
|
<slot :slot-scope="state.activeValue">
|
||||||
<input type="text" v-model="state.activeValue" :disabled="state.disabled" /><span>%</span>
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="state.slotValue"
|
||||||
|
@focus="handleSlotInputFocus"
|
||||||
|
@blur="handleSlotInputBlur"
|
||||||
|
@input="handleSlotInput"
|
||||||
|
:disabled="state.disabled"
|
||||||
|
/><span>%</span>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue