From 9cda914242234dd0673a31c6f5dc7a90aa4ad1f1 Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Mon, 14 Mar 2022 14:45:52 +0800
Subject: [PATCH] 完善数字增减框的交互功能设计,修复TaroUI数字框的输入问题

---
 forms/numberStep/CNumberStep.vue |  137 +++++++++++++++++++++++++++++++++------------
 1 files changed, 100 insertions(+), 37 deletions(-)

diff --git a/forms/numberStep/CNumberStep.vue b/forms/numberStep/CNumberStep.vue
index 0d49659..b9ec157 100644
--- a/forms/numberStep/CNumberStep.vue
+++ b/forms/numberStep/CNumberStep.vue
@@ -15,16 +15,17 @@
         />
         <view
             class="c-number-step-step"
-            :class="[unit?'on-unit':'', isEmpty?'on-empty':'']"
+            :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=>handleChange(evt)"
+                :value="itemRes.formData[itemRes.name] || ''"
+                :onChange="evt => handleChange(evt)"
             />
             <view class="c-number-step-unit">{{unit}}</view>
         </view>
@@ -70,52 +71,114 @@
         },
     },
     data() {
-        return {};
+        return {
+            dirty: false,
+        };
     },
     computed: {
-        // 空值判断,弥补空值时显示最小值的问题
-        isEmpty() {
-            const curVal = this.itemRes.formData[this.itemRes.name];
-            if (typeof curVal === 'undefined') {
+        // 脏值检查
+        isDirty() {
+            // 如果已脏
+            if (this.dirty) {
                 return true;
-            } else if (!curVal && curVal !== 0) {
-                return true;
-            } else {
-                return false;
             }
+            // 未脏时,如果不是无效值也视为脏
+            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) {
-            // 奇偶修正模式
-            if (this.correct) {
-                const lastValue = this.isEmpty
-                    ? this.range[0]
-                    : this.itemRes.formData[this.itemRes.name];
-                let nextValue = val;
-                if (
-                    (this.correct === 'odd' && nextValue % 2 === 0) ||
-                    (this.correct === 'even' && nextValue % 2 === 1)
-                ) {
-                    // 增加
-                    if (lastValue <= nextValue) {
-                        nextValue++;
-                    }
-                    // 减小
-                    else if (lastValue > nextValue) {
-                        nextValue--;
-                    }
-                }
-                // 范围
-                nextValue = Math.max(nextValue, this.range[0]);
-                nextValue = Math.min(nextValue, this.range[1]);
-                this.itemRes.onChange(nextValue);
+            this.dirty = true;
+            // 当数值等于边界时,按输入框值处理
+            if (val === this.range[0] || val === this.range[1]) {
+                this._checkInputVal(val);
             }
-            // 正常模式
+            // 范围内,按普通操作
             else {
-                this.itemRes.onChange(val);
+                // 奇偶修正模式
+                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') {

--
Gitblit v1.9.1