Quellcode durchsuchen

DatePicker: fix, add test for unwanted 'input' event emission

Fixes issue: https://github.com/ElemeFE/element/issues/4624
wacky6 vor 8 Jahren
Ursprung
Commit
3902bcc3e8
2 geänderte Dateien mit 134 neuen und 1 gelöschten Zeilen
  1. 18 1
      packages/date-picker/src/picker.vue
  2. 116 0
      test/unit/specs/date-picker.spec.js

+ 18 - 1
packages/date-picker/src/picker.vue

@@ -182,6 +182,20 @@ const PLACEMENT_MAP = {
   right: 'bottom-end'
 };
 
+// only considers date-picker's value: Date or [Date, Date]
+const valueEquals = function(a, b) {
+  const aIsArray = a instanceof Array;
+  const bIsArray = b instanceof Array;
+  if (aIsArray && bIsArray) {
+    return new Date(a[0]).getTime() === new Date(b[0]).getTime() &&
+           new Date(a[1]).getTime() === new Date(b[1]).getTime();
+  }
+  if (!aIsArray && !bIsArray) {
+    return new Date(a).getTime() === new Date(b).getTime();
+  }
+  return false;
+};
+
 export default {
   mixins: [Emitter, NewPopper],
 
@@ -470,7 +484,10 @@ export default {
 
       this.picker.$on('dodestroy', this.doDestroy);
       this.picker.$on('pick', (date = '', visible = false) => {
-        this.$emit('input', date);
+        // do not emit if values are same
+        if (!valueEquals(this.value, date)) {
+          this.$emit('input', date);
+        }
         this.pickerVisible = this.picker.visible = visible;
         this.picker.resetView && this.picker.resetView();
       });

+ 116 - 0
test/unit/specs/date-picker.spec.js

@@ -202,6 +202,122 @@ describe('DatePicker', () => {
     }, DELAY);
   });
 
+  describe('input event', () => {
+    // mimic standard <select>'s behavior
+    // emit input if and only if value changes
+    afterEach(() => {
+      destroyVM(vm);
+    });
+
+    it('works for type=date', done => {
+      let emitted = false;
+      vm = createVue({
+        template: `
+          <el-date-picker
+            ref="compo"
+            v-model="value"
+            type="date"
+            @input="handleInput" />`,
+
+        methods: {
+          handleInput(val) {
+            emitted = true;
+          }
+        },
+
+        data() {
+          return {
+            value: ''
+          };
+        }
+      }, true);
+
+      const input = vm.$el.querySelector('input');
+
+      input.blur();
+      input.focus();
+
+      setTimeout(_ => {
+        const picker = vm.$refs.compo.picker;
+
+        picker.$el.querySelector('td.available').click();
+        setTimeout(_ => {
+          expect(emitted).to.true;
+          emitted = false;
+
+          setTimeout(_ => {
+            input.blur();
+            input.focus();
+
+            picker.$el.querySelector('td.available').click();
+            setTimeout(_ => {
+              expect(emitted).to.false;
+              done();
+            }, DELAY);
+          }, DELAY);
+        }, DELAY);
+      }, DELAY);
+    });
+
+    it('works for type=daterange', done => {
+      let emitted = false;
+      vm = createVue({
+        template: `
+          <el-date-picker
+            ref="compo"
+            v-model="value"
+            type="daterange"
+            @input="handleInput" />`,
+
+        methods: {
+          handleInput(val) {
+            emitted = true;
+          }
+        },
+
+        data() {
+          return {
+            value: ''
+          };
+        }
+      }, true);
+
+      const input = vm.$el.querySelector('input');
+
+      input.blur();
+      input.focus();
+
+      setTimeout(_ => {
+        const picker = vm.$refs.compo.picker;
+
+        picker.$el.querySelector('td.available').click();
+        setTimeout(_ => {
+          picker.$el.querySelector('td.available + td.available').click();
+          setTimeout(_ => {
+            expect(emitted).to.true;
+            emitted = false;
+
+            setTimeout(_ => {
+              input.blur();
+              input.focus();
+
+              const picker = vm.$refs.compo.picker;
+              picker.$el.querySelector('td.available').click();
+              setTimeout(_ => {
+                picker.$el.querySelector('td.available + td.available').click();
+                setTimeout(_ => {
+                  expect(emitted).to.false;
+                  done();
+                });
+              }, DELAY);
+            }, DELAY);
+          });
+        }, DELAY);
+      }, DELAY);
+    });
+
+  });
+
   it('default value', done => {
     const toDateStr = date => {
       let d = new Date(date);