浏览代码

fix(input): blur event bug #438

richard1015 4 年之前
父节点
当前提交
cb213e828b
共有 3 个文件被更改,包括 99 次插入113 次删除
  1. 8 8
      src/packages/input/demo.vue
  2. 62 19
      src/packages/input/doc.md
  3. 29 86
      src/packages/input/index.vue

+ 8 - 8
src/packages/input/demo.vue

@@ -79,17 +79,17 @@ export default createDemo({
     setTimeout(function() {
       state.val1 = '异步数据';
     }, 2000);
-    const change = (num: string | number) => {
-      console.log('change: ', num);
+    const change = (value: string | number, event: Event) => {
+      console.log('change: ', value, event);
     };
-    const focus = (num: string | number) => {
-      console.log('focus:', num);
+    const focus = (value: string | number, event: Event) => {
+      console.log('focus:', value, event);
     };
-    const blur = (num: string | number) => {
-      console.log('blur:', num);
+    const blur = (value: string | number, event: Event) => {
+      console.log('blur:', value, event);
     };
-    const clear = (num: string | number) => {
-      console.log('clear:', num);
+    const clear = (value: string | number) => {
+      console.log('clear:', value);
     };
 
     return {

+ 62 - 19
src/packages/input/doc.md

@@ -58,30 +58,73 @@ app.use(Input);
 <nut-input v-model="state.val6" @change="change" type="digit" placeholder="支持小数点的输入" label="数字"/>
 ```
 
-
+### 代码
+```html
+import { reactive } from 'vue';
+import { createComponent } from '@/utils/create';
+const { createDemo } = createComponent('input');
+export default createDemo({
+  setup() {
+    const state = reactive({
+      val0: '',
+      val1: '初始数据',
+      val2: '禁止修改',
+      val3: 'readonly 只读',
+      val4: '',
+      val5: '',
+      val6: '',
+      val7: '',
+      val8: '文案'
+    });
+    setTimeout(function() {
+      state.val1 = '异步数据';
+    }, 2000);
+    const change = (value: string | number,event:Event) => {
+      console.log('change: ', value,event);
+    };
+    const focus = (value: string | number,event:Event) => {
+      console.log('focus:', value,event);
+    };
+    const blur = (value: string | number,event:Event) => {
+      console.log('blur:', value,event);
+    };
+    const clear = (value: string | number) => {
+      console.log('clear:', value);
+    };
+
+    return {
+      state,
+      change,
+      blur,
+      clear,
+      focus
+    };
+  }
+});
+```
 ### Prop
 
-| 参数          | 说明                                   | 类型           | 默认值  |
-|---------------|----------------------------------------|----------------|---------|
-| v-model         | 输入值,双向绑定                       | String         | -       |
-| type          | 类型,可选值为 `text` `number`  等     | String         | `text`  |
-| placeholder   | 为空时占位符                           | String         | -       |
-| label         | 左侧文案                               | String         | -       |
-| require-show  | 左侧*号是否展示                        | Boolean        | `false` |
-| disabled      | 是否禁用                               | Boolean        | `false` |
-| readonly      | 是否只读                               | Boolean        | `false` |
-| max-length    | 限制最长输入字符                       | String、Number | -       |
-| disable-clear | 禁止展示清除icon                       | Boolean        | `false` |
-| text-align    | 文本位置,可选值`left`,`center`,`right` | String         | `left`  |
+| 参数         | 说明                                   | 类型           | 默认值  |
+|--------------|----------------------------------------|----------------|---------|
+| v-model      | 输入值,双向绑定                       | String         | -       |
+| type         | 类型,可选值为 `text` `number`  等     | String         | `text`  |
+| placeholder  | 为空时占位符                           | String         | -       |
+| label        | 左侧文案                               | String         | -       |
+| require-show | 左侧*号是否展示                        | Boolean        | `false` |
+| disabled     | 是否禁用                               | Boolean        | `false` |
+| readonly     | 是否只读                               | Boolean        | `false` |
+| max-length   | 限制最长输入字符                       | String、Number | -       |
+| clearable    | 展示清除icon                           | Boolean        | `true`  |
+| text-align   | 文本位置,可选值`left`,`center`,`right` | String         | `left`  |
 
 ### Event
 
-| 名称   | 说明           | 回调参数 |
-|--------|----------------|----------|
-| change | 输入内容时触发 | val      |
-| focus  | 聚焦时触发     | val      |
-| blur   | 失焦时触发     | val      |
-| clear  | 点击清空时触发 | val      |
+| 名称   | 说明           | 回调参数    |
+|--------|----------------|-------------|
+| change | 输入内容时触发 | val ,event  |
+| focus  | 聚焦时触发     | val  ,event |
+| blur   | 失焦时触发     | val ,event  |
+| clear  | 点击清空时触发 | val         |
 
 
 

+ 29 - 86
src/packages/input/index.vue

@@ -12,7 +12,7 @@
       :placeholder="placeholder"
       :disabled="disabled"
       :readonly="readonly"
-      :value="curretvalue"
+      :value="modelValue"
       @input="valueChange"
       @focus="valueFocus"
       @blur="valueBlur"
@@ -20,21 +20,21 @@
     <view
       @click="handleClear"
       class="nut-textinput-clear"
-      v-if="!disableClear && !readonly"
-      v-show="active && curretvalue.length > 0"
+      v-if="clearable && !readonly"
+      v-show="active && modelValue.length > 0"
     >
       <nut-icon name="close-little" size="12px"></nut-icon>
     </view>
   </view>
 </template>
 <script lang="ts">
-import { toRefs, reactive, computed, watch } from 'vue';
+import { ref, computed } from 'vue';
 import { createComponent } from '@/utils/create';
 import { formatNumber } from './util';
 
 const { componentName, create } = createComponent('input');
 interface Events {
-  eventName: 'change' | 'focus' | 'blur' | 'clear' | 'update:value';
+  eventName: 'change' | 'focus' | 'blur' | 'clear' | 'update:modelValue';
   params: (string | number | Event)[];
 }
 export default create({
@@ -43,7 +43,7 @@ export default create({
       type: String,
       default: 'text'
     },
-    value: {
+    modelValue: {
       type: [String, Number],
       default: ''
     },
@@ -75,20 +75,16 @@ export default create({
       type: [String, Number],
       default: ''
     },
-    disableClear: {
+    clearable: {
       type: Boolean,
-      default: false
+      default: true
     }
   },
 
-  emits: ['change', 'update:value', 'blur', 'focus', 'clear'],
+  emits: ['change', 'update:modelValue', 'blur', 'focus', 'clear'],
 
   setup(props, { emit }) {
-    const state = reactive({
-      curretvalue: props.value,
-      textNum: String(props.value).length,
-      active: false
-    });
+    const active = ref(false);
 
     const classes = computed(() => {
       const prefixCls = componentName;
@@ -104,14 +100,8 @@ export default create({
       };
     });
 
-    const emitChange = (envs: Array<Events>) => {
-      envs.forEach((item: Events) => {
-        return emit(item.eventName, ...item.params);
-      });
-    };
-
-    const valueChange = (e: Event) => {
-      const input = e.target as HTMLInputElement;
+    const valueChange = (event: Event) => {
+      const input = event.target as HTMLInputElement;
       let val = input.value;
 
       if (props.maxLength && val.length > Number(props.maxLength)) {
@@ -123,79 +113,32 @@ export default create({
       if (props.type === 'number') {
         val = formatNumber(val, false);
       }
-      state.textNum = val.length;
-      emitChange([
-        {
-          eventName: 'update:value',
-          params: [val]
-        },
-        {
-          eventName: 'change',
-          params: [val]
-        }
-      ]);
+      emit('change', val, event);
+      emit('update:modelValue', val, event);
     };
 
-    const valueFocus = (e: Event) => {
-      state.active = true;
-      const input = e.target as HTMLInputElement;
-      emitChange([
-        {
-          eventName: 'update:value',
-          params: [state.curretvalue]
-        },
-        {
-          eventName: 'focus',
-          params: [String(input.value)]
-        }
-      ]);
+    const valueFocus = (event: Event) => {
+      const input = event.target as HTMLInputElement;
+      let value = input.value;
+      active.value = true;
+      emit('focus', value, event);
     };
 
-    const valueBlur = (e: Event) => {
-      setTimeout(() => {
-        state.active = false;
-      }, 400);
-      const input = e.target as HTMLInputElement;
-      emitChange([
-        {
-          eventName: 'update:value',
-          params: [String(input.value)]
-        },
-        {
-          eventName: 'blur',
-          params: [String(input.value)]
-        }
-      ]);
-    };
+    const valueBlur = (event: Event) => {
+      active.value = false;
+      const input = event.target as HTMLInputElement;
+      let value = input.value;
 
-    const handleClear = () => {
-      emitChange([
-        {
-          eventName: 'update:value',
-          params: ['']
-        },
-        {
-          eventName: 'clear',
-          params: ['']
-        }
-      ]);
+      emit('blur', value, event);
     };
 
-    watch(
-      () => props.value,
-      val => {
-        state.curretvalue = val;
-        emitChange([
-          {
-            eventName: 'update:value',
-            params: [String(val)]
-          }
-        ]);
-      }
-    );
+    const handleClear = (event: Event) => {
+      emit('change', '', event);
+      emit('update:modelValue', '', event);
+    };
 
     return {
-      ...toRefs(state),
+      active,
       classes,
       styles,
       valueChange,