From f15b49c7d2294d01e8456217f23984b8ee2d73ae Mon Sep 17 00:00:00 2001 From: rex Date: Tue, 10 Mar 2020 15:08:17 +0800 Subject: [PATCH] refactor(Stepper): not format in input & improve performance (#2841) --- packages/stepper/index.ts | 165 +++++++++++++++++++----------------- packages/stepper/index.wxml | 12 +-- 2 files changed, 92 insertions(+), 85 deletions(-) diff --git a/packages/stepper/index.ts b/packages/stepper/index.ts index c9ec2f4d..d3bfd84f 100644 --- a/packages/stepper/index.ts +++ b/packages/stepper/index.ts @@ -1,16 +1,20 @@ import { VantComponent } from '../common/component'; 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_INTERVAL = 200; // add num and avoid float number -function add(num1: number, num2: number): number { +function add(num1: number, num2: number) { const cardinal = 10 ** 10; return Math.round((num1 + num2) * cardinal) / cardinal; } +function equal(value1: number | string, value2: number | string) { + return String(value1) === String(value2); +} + VantComponent({ field: true, @@ -20,49 +24,34 @@ VantComponent({ value: { type: null, observer(value) { - if (value === '') { - return; + if (!equal(value, this.data.currentValue)) { + this.setData({ currentValue: this.format(value) }); } - - const newValue = this.range(value); - - if (typeof newValue === 'number' && +this.data.value !== newValue) { - this.setData({ value: newValue }); - } - }, - }, - integer: Boolean, - disabled: Boolean, - inputWidth: { - type: null, - observer() { - this.setData({ - inputStyle: this.computeInputStyle() - }); - }, - }, - buttonSize: { - type: null, - observer() { - this.setData({ - inputStyle: this.computeInputStyle(), - buttonStyle: this.computeButtonStyle() - }); } }, + integer: { + type: Boolean, + observer: 'check' + }, + disabled: Boolean, + inputWidth: null, + buttonSize: null, asyncChange: Boolean, disableInput: Boolean, decimalLength: { type: Number, - value: null + value: null, + observer: 'check' }, min: { type: null, - value: 1 + value: 1, + observer: 'check' }, max: { type: null, - value: Number.MAX_SAFE_INTEGER + value: Number.MAX_SAFE_INTEGER, + observer: 'check' }, step: { type: null, @@ -81,28 +70,41 @@ VantComponent({ longPress: { type: Boolean, value: true - }, + } }, data: { - focus: false, - inputStyle: '', - buttonStyle: '' + currentValue: '' }, created() { this.setData({ - value: this.range(this.data.value) + currentValue: this.format(this.data.value) }); }, methods: { + check() { + const val = this.format(this.data.currentValue); + if (!equal(val, this.data.currentValue)) { + this.setData({ currentValue: val }); + } + }, + isDisabled(type: string) { 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) { @@ -110,14 +112,28 @@ VantComponent({ }, onBlur(event: Weapp.Event) { - const value = this.range(this.data.value); - this.triggerInput(value); - this.$emit('blur', event.detail); + const value = this.format(event.detail.value); + this.emitChange(value); + 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 - range(value) { - value = String(value).replace(/[^0-9.-]/g, ''); + format(value) { + value = this.filter(value); // format range value = value === '' ? 0 : +value; @@ -133,7 +149,29 @@ VantComponent({ onInput(event: Weapp.Event) { 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() { @@ -144,9 +182,10 @@ VantComponent({ } 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); }, @@ -185,38 +224,6 @@ VantComponent({ return; } 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; } } }); diff --git a/packages/stepper/index.wxml b/packages/stepper/index.wxml index 456ccced..95704208 100644 --- a/packages/stepper/index.wxml +++ b/packages/stepper/index.wxml @@ -4,8 +4,8 @@