Browse Source

fix input value binding bug (#1998)

* fix input value binding bug

* improve input test & docs
baiyaaaaa 8 years ago
parent
commit
6e428ffcc7

+ 4 - 1
examples/docs/en-US/input.md

@@ -591,7 +591,10 @@ Search data from server-side.
 
 | Event Name | Description | Parameters |
 |----| ----| ----|
-|click | triggers when the icon inside Input is clicked | event object |
+|click | triggers when the icon inside Input is clicked | (event: Event) |
+| blur | triggers when the icon inside Input is blur | (event: Event) |
+| focus | triggers when the icon inside Input is focus | (event: Event) |
+| change | triggers when the icon inside Input value change | (value: string \| number) |
 
 ### Autocomplete Attributes
 

+ 4 - 3
examples/docs/zh-CN/input.md

@@ -759,9 +759,10 @@ export default {
 ### Input Events
 | 事件名称 | 说明 | 回调参数 |
 |---------|--------|---------|
-| click | 点击 Input 内的图标时触发 | event |
-| blur | 在 Input 失去焦点时触发 | event |
-| focus | 在 Input 或得焦点时触发 | event |
+| click | 点击 Input 内的图标时触发 | (event: Event) |
+| blur | 在 Input 失去焦点时触发 | (event: Event) |
+| focus | 在 Input 或得焦点时触发 | (event: Event) |
+| change | 在 Input 值改变时触发 | (value: string \| number) |
 
 ### Autocomplete Attributes
 

+ 32 - 29
packages/input/src/input.vue

@@ -33,7 +33,7 @@
         :min="min"
         :max="max"
         :form="form"
-        :value="value"
+        :value="currentValue"
         ref="input"
         @input="handleInput"
         @focus="handleFocus"
@@ -76,6 +76,13 @@
 
     mixins: [emitter],
 
+    data() {
+      return {
+        currentValue: this.value,
+        textareaStyle: {}
+      };
+    },
+
     props: {
       value: [String, Number],
       placeholder: String,
@@ -108,10 +115,23 @@
       min: {}
     },
 
+    computed: {
+      validating() {
+        return this.$parent.validateState === 'validating';
+      }
+    },
+
+    watch: {
+      'value'(val, oldValue) {
+        this.setCurrentValue(val);
+      }
+    },
+
     methods: {
       handleBlur(event) {
         this.$emit('blur', event);
         this.dispatch('ElFormItem', 'el.form.blur', [this.currentValue]);
+        this.currentValue = this.value;
       },
       inputSelect() {
         this.$refs.input.select();
@@ -130,46 +150,29 @@
         this.$emit('focus', event);
       },
       handleInput(event) {
-        this.currentValue = event.target.value;
+        this.setCurrentValue(event.target.value);
       },
       handleIconClick(event) {
         this.$emit('click', event);
+      },
+      setCurrentValue(value) {
+        if (value === this.currentValue) return;
+        this.$nextTick(_ => {
+          this.resizeTextarea();
+        });
+        this.currentValue = value;
+        this.$emit('input', value);
+        this.$emit('change', value);
+        this.dispatch('ElFormItem', 'el.form.change', [value]);
       }
     },
 
-    data() {
-      return {
-        currentValue: this.value,
-        textareaStyle: {}
-      };
-    },
-
     created() {
       this.$on('inputSelect', this.inputSelect);
     },
 
     mounted() {
       this.resizeTextarea();
-    },
-
-    computed: {
-      validating() {
-        return this.$parent.validateState === 'validating';
-      }
-    },
-
-    watch: {
-      'value'(val, oldValue) {
-        this.currentValue = val;
-      },
-      'currentValue'(val) {
-        this.$nextTick(_ => {
-          this.resizeTextarea();
-        });
-        this.$emit('input', val);
-        this.$emit('change', val);
-        this.dispatch('ElFormItem', 'el.form.change', [val]);
-      }
     }
   };
 </script>

+ 54 - 0
test/unit/specs/input.spec.js

@@ -104,6 +104,7 @@ describe('Input', () => {
     }, true);
     expect(vm.$el.querySelector('.el-textarea__inner').getAttribute('rows')).to.be.equal('3');
   });
+
   it('autosize', done => {
     vm = createVue({
       template: `
@@ -143,4 +144,57 @@ describe('Input', () => {
       done();
     }, 200);
   });
+
+  describe('Input Events', () => {
+    it('event:focus & blur', done => {
+      vm = createVue({
+        template: `
+          <el-input
+            ref="input"
+            placeholder="请输入内容"
+            value="input">
+          </el-input>
+        `
+      }, true);
+
+      const spyFocus = sinon.spy();
+      const spyBlur = sinon.spy();
+
+      vm.$refs.input.$on('focus', spyFocus);
+      vm.$refs.input.$on('blur', spyBlur);
+      vm.$el.querySelector('input').focus();
+      vm.$el.querySelector('input').blur();
+
+      vm.$nextTick(_ => {
+        expect(spyFocus.calledOnce).to.be.true;
+        expect(spyBlur.calledOnce).to.be.true;
+        done();
+      });
+    });
+    it('event:change', done => {
+      vm = createVue({
+        template: `
+          <el-input
+            ref="input"
+            placeholder="请输入内容"
+            :value="input">
+          </el-input>
+        `,
+        data() {
+          return {
+            input: 'a'
+          };
+        }
+      }, true);
+
+      const spy = sinon.spy();
+      vm.$refs.input.$on('change', spy);
+      vm.input = 'b';
+
+      vm.$nextTick(_ => {
+        expect(spy.withArgs('b').calledOnce).to.be.true;
+        done();
+      });
+    });
+  });
 });