mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-06 03:58:05 +08:00
refactor(Stepper): not format in input & improve performance (#2841)
This commit is contained in:
parent
9e8d5dcf7e
commit
f15b49c7d2
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user