refactor(Stepper): not format in input & improve performance (#2841)

This commit is contained in:
rex 2020-03-10 15:08:17 +08:00 committed by GitHub
parent 9e8d5dcf7e
commit f15b49c7d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 85 deletions

View File

@ -1,16 +1,20 @@
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { Weapp } from 'definitions/weapp'; import { Weapp } from 'definitions/weapp';
import { addUnit, isDef } from '../common/utils'; import { isDef } from '../common/utils';
const LONG_PRESS_START_TIME = 600; const LONG_PRESS_START_TIME = 600;
const LONG_PRESS_INTERVAL = 200; const LONG_PRESS_INTERVAL = 200;
// add num and avoid float number // add num and avoid float number
function add(num1: number, num2: number): number { function add(num1: number, num2: number) {
const cardinal = 10 ** 10; const cardinal = 10 ** 10;
return Math.round((num1 + num2) * cardinal) / cardinal; return Math.round((num1 + num2) * cardinal) / cardinal;
} }
function equal(value1: number | string, value2: number | string) {
return String(value1) === String(value2);
}
VantComponent({ VantComponent({
field: true, field: true,
@ -20,49 +24,34 @@ VantComponent({
value: { value: {
type: null, type: null,
observer(value) { observer(value) {
if (value === '') { if (!equal(value, this.data.currentValue)) {
return; this.setData({ currentValue: this.format(value) });
} }
const newValue = this.range(value);
if (typeof newValue === 'number' && +this.data.value !== newValue) {
this.setData({ value: newValue });
} }
}, },
integer: {
type: Boolean,
observer: 'check'
}, },
integer: Boolean,
disabled: Boolean, disabled: Boolean,
inputWidth: { inputWidth: null,
type: null, buttonSize: null,
observer() {
this.setData({
inputStyle: this.computeInputStyle()
});
},
},
buttonSize: {
type: null,
observer() {
this.setData({
inputStyle: this.computeInputStyle(),
buttonStyle: this.computeButtonStyle()
});
}
},
asyncChange: Boolean, asyncChange: Boolean,
disableInput: Boolean, disableInput: Boolean,
decimalLength: { decimalLength: {
type: Number, type: Number,
value: null value: null,
observer: 'check'
}, },
min: { min: {
type: null, type: null,
value: 1 value: 1,
observer: 'check'
}, },
max: { max: {
type: null, type: null,
value: Number.MAX_SAFE_INTEGER value: Number.MAX_SAFE_INTEGER,
observer: 'check'
}, },
step: { step: {
type: null, type: null,
@ -81,28 +70,41 @@ VantComponent({
longPress: { longPress: {
type: Boolean, type: Boolean,
value: true value: true
}, }
}, },
data: { data: {
focus: false, currentValue: ''
inputStyle: '',
buttonStyle: ''
}, },
created() { created() {
this.setData({ this.setData({
value: this.range(this.data.value) currentValue: this.format(this.data.value)
}); });
}, },
methods: { methods: {
check() {
const val = this.format(this.data.currentValue);
if (!equal(val, this.data.currentValue)) {
this.setData({ currentValue: val });
}
},
isDisabled(type: string) { isDisabled(type: string) {
if (type === 'plus') { if (type === 'plus') {
return this.data.disabled || this.data.disablePlus || this.data.value >= this.data.max; return (
this.data.disabled ||
this.data.disablePlus ||
this.data.currentValue >= this.data.max
);
} }
return this.data.disabled || this.data.disableMinus || this.data.value <= this.data.min; return (
this.data.disabled ||
this.data.disableMinus ||
this.data.currentValue <= this.data.min
);
}, },
onFocus(event: Weapp.Event) { onFocus(event: Weapp.Event) {
@ -110,14 +112,28 @@ VantComponent({
}, },
onBlur(event: Weapp.Event) { onBlur(event: Weapp.Event) {
const value = this.range(this.data.value); const value = this.format(event.detail.value);
this.triggerInput(value); this.emitChange(value);
this.$emit('blur', event.detail); this.$emit('blur', {
...event.detail,
value
});
},
// filter illegal characters
filter(value) {
value = String(value).replace(/[^0-9.-]/g, '');
if (this.data.integer && value.indexOf('.') !== -1) {
value = value.split('.')[0];
}
return value;
}, },
// limit value range // limit value range
range(value) { format(value) {
value = String(value).replace(/[^0-9.-]/g, ''); value = this.filter(value);
// format range // format range
value = value === '' ? 0 : +value; value = value === '' ? 0 : +value;
@ -133,7 +149,29 @@ VantComponent({
onInput(event: Weapp.Event) { onInput(event: Weapp.Event) {
const { value = '' } = event.detail || {}; const { value = '' } = event.detail || {};
this.triggerInput(value);
// allow input to be empty
if (value === '') {
return;
}
let formatted = this.filter(value);
// limit max decimal length
if (isDef(this.data.decimalLength) && formatted.indexOf('.') !== -1) {
const pair = formatted.split('.');
formatted = `${pair[0]}.${pair[1].slice(0, this.data.decimalLength)}`;
}
this.emitChange(formatted);
},
emitChange(value: string) {
if (!this.data.asyncChange) {
this.setData({ currentValue: value });
}
this.$emit('change', value);
}, },
onChange() { onChange() {
@ -144,9 +182,10 @@ VantComponent({
} }
const diff = type === 'minus' ? -this.data.step : +this.data.step; const diff = type === 'minus' ? -this.data.step : +this.data.step;
const value = add(+this.data.value, diff);
this.triggerInput(this.range(value)); const value = this.format(add(+this.data.currentValue, diff));
this.emitChange(value);
this.$emit(type); this.$emit(type);
}, },
@ -185,38 +224,6 @@ VantComponent({
return; return;
} }
clearTimeout(this.longPressTimer); clearTimeout(this.longPressTimer);
},
triggerInput(value: string) {
this.setData({
value: this.data.asyncChange ? this.data.value : value
});
this.$emit('change', value);
},
computeInputStyle() {
let style = '';
if (this.data.inputWidth) {
style = `width: ${addUnit(this.data.inputWidth)};`;
}
if (this.data.buttonSize) {
style += `height: ${addUnit(this.data.buttonSize)};`;
}
return style;
},
computeButtonStyle() {
let style = '';
const size = addUnit(this.data.buttonSize);
if (this.data.buttonSize) {
style = `width: ${size};height: ${size};`;
}
return style;
} }
} }
}); });

View File

@ -4,8 +4,8 @@
<view <view
wx:if="{{ showMinus }}" wx:if="{{ showMinus }}"
data-type="minus" data-type="minus"
style="{{ buttonStyle }}" style="width: {{ utils.addUnit(buttonSize) }}; height: {{ utils.addUnit(buttonSize) }}"
class="minus-class {{ utils.bem('stepper__minus', { disabled: disabled || disableMinus || value <= min }) }}" class="minus-class {{ utils.bem('stepper__minus', { disabled: disabled || disableMinus || currentValue <= min }) }}"
hover-class="van-stepper__minus--hover" hover-class="van-stepper__minus--hover"
hover-stay-time="70" hover-stay-time="70"
bind:tap="onTap" bind:tap="onTap"
@ -15,8 +15,8 @@
<input <input
type="{{ integer ? 'number' : 'digit' }}" type="{{ integer ? 'number' : 'digit' }}"
class="input-class {{ utils.bem('stepper__input', { disabled: disabled || disableInput }) }}" class="input-class {{ utils.bem('stepper__input', { disabled: disabled || disableInput }) }}"
style="{{ inputStyle }}" style="width: {{ utils.addUnit(inputWidth) }}; height: {{ utils.addUnit(buttonSize) }}"
value="{{ value }}" value="{{ currentValue }}"
focus="{{ focus }}" focus="{{ focus }}"
disabled="{{ disabled || disableInput }}" disabled="{{ disabled || disableInput }}"
bindinput="onInput" bindinput="onInput"
@ -26,8 +26,8 @@
<view <view
wx:if="{{ showPlus }}" wx:if="{{ showPlus }}"
data-type="plus" data-type="plus"
style="{{ buttonStyle }}" style="width: {{ utils.addUnit(buttonSize) }}; height: {{ utils.addUnit(buttonSize) }}"
class="plus-class {{ utils.bem('stepper__plus', { disabled: disabled || disablePlus || value >= max }) }}" class="plus-class {{ utils.bem('stepper__plus', { disabled: disabled || disablePlus || currentValue >= max }) }}"
hover-class="van-stepper__plus--hover" hover-class="van-stepper__plus--hover"
hover-stay-time="70" hover-stay-time="70"
bind:tap="onTap" bind:tap="onTap"