| | |
| | | /** |
| | | * CNumberStep |
| | | * 数字步进器组件,用于在表单中输入数字并通过步进按钮增减数值 |
| | | * 支持设置数值范围、步长、奇偶修正和单位显示 |
| | | * @author Tevin |
| | | */ |
| | | |
| | |
| | | /> |
| | | <view |
| | | class="c-number-step-step" |
| | | :class="unit?'on-unit':''" |
| | | :class="[unit?'on-unit':'', isDirty?'':'not-dirty']" |
| | | ref="number" |
| | | @tap="evt=>handleOpr()" |
| | | > |
| | | <AtInputNumber |
| | | :min="range[0]" |
| | | :max="range[1]" |
| | | :step="step" |
| | | :width="120" |
| | | :value="itemRes.formData[itemRes.name]" |
| | | :onChange="evt=>itemRes.onChange(evt)" |
| | | :value="itemRes.formData[itemRes.name] || ''" |
| | | :onChange="evt => handleChange(evt)" |
| | | /> |
| | | <view class="c-number-step-unit">{{unit}}</view> |
| | | </view> |
| | |
| | | // 取值范围 |
| | | range: { |
| | | type: Array, |
| | | default: [0, 100], |
| | | default: () => [0, 100], |
| | | }, |
| | | // 步长 |
| | | step: { |
| | | type: Number, |
| | | default: 1, |
| | | }, |
| | | // 奇偶修正 odd 奇数 / even 偶数 |
| | | correct: { |
| | | type: String, |
| | | default: '', |
| | | }, |
| | | // 数值单位 |
| | | unit: { |
| | |
| | | }, |
| | | }, |
| | | data() { |
| | | return {}; |
| | | return { |
| | | dirty: false, |
| | | }; |
| | | }, |
| | | computed: {}, |
| | | methods: {}, |
| | | computed: { |
| | | // 脏值检查 |
| | | isDirty() { |
| | | // 如果已脏 |
| | | if (this.dirty) { |
| | | return true; |
| | | } |
| | | // 未脏时,如果不是无效值也视为脏 |
| | | return !this.isInvalid; |
| | | }, |
| | | // 是否为无效值 |
| | | isInvalid() { |
| | | const itemValue = this.itemRes.formData[this.itemRes.name]; |
| | | if (typeof itemValue === 'undefined') { |
| | | return true; |
| | | } |
| | | if (typeof itemValue === 'string' && !itemValue) { |
| | | return true; |
| | | } |
| | | if (typeof itemValue === 'object' && !itemValue) { |
| | | return true; |
| | | } |
| | | return false; |
| | | }, |
| | | }, |
| | | methods: { |
| | | handleOpr() { |
| | | this.dirty = true; |
| | | if (this.isInvalid) { |
| | | this.itemRes.onChange(this.range[0]); |
| | | } |
| | | }, |
| | | handleChange(val) { |
| | | this.dirty = true; |
| | | // 当数值等于边界时,按输入框值处理 |
| | | if (val === this.range[0] || val === this.range[1]) { |
| | | this._checkInputVal(val); |
| | | } |
| | | // 范围内,按普通操作 |
| | | else { |
| | | // 奇偶修正模式 |
| | | if (this.correct) { |
| | | const lastValue = |
| | | this.itemRes.formData[this.itemRes.name] || this.range[0]; |
| | | let nextValue = val; |
| | | // 奇偶不满足时 |
| | | if ( |
| | | (this.correct === 'odd' && nextValue % 2 === 0) || |
| | | (this.correct === 'even' && nextValue % 2 === 1) |
| | | ) { |
| | | // 如果新值变大,则再增加一次 |
| | | if (lastValue <= nextValue) { |
| | | // 如果加1没有范围约束,则再次加1 |
| | | if (nextValue + 1 <= this.range[1]) { |
| | | nextValue++; |
| | | } |
| | | // 否则,减1 |
| | | else { |
| | | nextValue--; |
| | | } |
| | | } |
| | | // 如果新值变小,则再减小一次 |
| | | else if (lastValue > nextValue) { |
| | | // 如果再减1没有超过约束范围,则再减1 |
| | | if (nextValue - 1 >= this.range[0]) { |
| | | nextValue--; |
| | | } |
| | | // 否则,加1 |
| | | else { |
| | | nextValue++; |
| | | } |
| | | } |
| | | } |
| | | // 奇偶满足时 |
| | | else { |
| | | // 范围约束 |
| | | nextValue = Math.max(nextValue, this.range[0]); |
| | | nextValue = Math.min(nextValue, this.range[1]); |
| | | } |
| | | this.itemRes.onChange(nextValue); |
| | | } |
| | | // 正常模式 |
| | | else { |
| | | this.itemRes.onChange(val); |
| | | } |
| | | } |
| | | }, |
| | | _checkInputVal(realValue) { |
| | | const $input = $(this.$refs.input.$el).find('.c-number-step-step input'); |
| | | if ($input) { |
| | | const inputValue = $input.val(); |
| | | // 删除值 |
| | | if (inputValue === '') { |
| | | this.dirty = false; |
| | | this.itemRes.onChange(''); |
| | | return; |
| | | } |
| | | // 超过边界 |
| | | if (inputValue != realValue) { |
| | | $input.val(realValue); |
| | | } |
| | | } |
| | | this.itemRes.onChange(realValue); |
| | | }, |
| | | }, |
| | | mounted() { |
| | | if (process.env.TARO_ENV === 'h5') { |
| | | $(this.$refs.input.$el) |
| | | .find('.at-input__input') |
| | | .find('.at-input__container') |
| | | .prepend(this.$refs.number.$el); |
| | | } else if (process.env.TARO_ENV === 'weapp') { |
| | | $(this.$refs.input.$el) |