浏览代码

Merge pull request #1956 from QingWei-Li/fix/date-picker-input-event

DatePicker: input event is not fired when the array value is not upda…
baiyaaaaa 8 年之前
父节点
当前提交
d1f9357df7

+ 7 - 1
examples/docs/en-US/date-picker.md

@@ -274,4 +274,10 @@ Picking a date range is supported.
 | Attribute      | Description          | Type      | Accepted Values       | Default  |
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | text | title of the shortcut | string | — | — |
-| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — |
+| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — |
+
+
+### Events
+| Event Name | Description | Parameters |
+|---------|--------|---------|
+| change | triggers when input value changes | formatted value |

+ 7 - 0
examples/docs/en-US/datetime-picker.md

@@ -230,3 +230,10 @@ Select date and time in one picker.
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | text | title of the shortcut | string | — | — |
 | onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — |
+
+
+### Events
+| Event Name | Description | Parameters |
+|---------|--------|---------|
+| change | triggers when input value changes | formatted value |
+

+ 7 - 0
examples/docs/en-US/time-picker.md

@@ -167,3 +167,10 @@ Can pick an arbitrary time range.
 | Attribute      | Description          | Type      | Accepted Values       | Default  |
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | selectableRange | available time range, e.g.`'18:30:00 - 20:30:00'`or`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string/array | — | — |
+
+
+### Events
+| Event Name | Description | Parameters |
+|---------|--------|---------|
+| change | triggers when input value changes | formatted value |
+

+ 6 - 0
examples/docs/zh-CN/date-picker.md

@@ -309,3 +309,9 @@
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | text | 标题文本 | string | — | — |
 | onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | function | — | — |
+
+### Events
+| Event Name | Description | Parameters |
+|---------|--------|---------|
+| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
+

+ 6 - 0
examples/docs/zh-CN/datetime-picker.md

@@ -255,3 +255,9 @@
 | onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | function | — | — |
 
 
+### Events
+| Event Name | Description | Parameters |
+|---------|--------|---------|
+| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
+
+

+ 8 - 0
examples/docs/zh-CN/time-picker.md

@@ -175,3 +175,11 @@
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | selectableRange | 可选时间段,例如`'18:30:00 - 20:30:00'`或者传入数组`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string/array | — | — |
 
+
+### Events
+| Event Name | Description | Parameters |
+|---------|--------|---------|
+| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
+
+
+

+ 4 - 6
packages/date-picker/src/panel/date-range.vue

@@ -293,7 +293,7 @@
       handleClear() {
         this.minDate = null;
         this.maxDate = null;
-        this.handleConfirm();
+        this.handleConfirm(false);
       },
 
       handleDateInput(event, type) {
@@ -376,10 +376,8 @@
         this.maxDate = val.maxDate;
         this.minDate = val.minDate;
 
-        if (!close) return;
-        if (!this.showTime) {
-          this.$emit('pick', [this.minDate, this.maxDate]);
-        }
+        if (!close || this.showTime) return;
+        this.handleConfirm();
       },
 
       changeToToday() {
@@ -456,7 +454,7 @@
         this.resetDate();
       },
 
-      handleConfirm(visible) {
+      handleConfirm(visible = false) {
         this.$emit('pick', [this.minDate, this.maxDate], visible);
       },
 

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

@@ -189,7 +189,7 @@
     methods: {
       handleClear() {
         this.date = new Date();
-        this.$emit('pick', '');
+        this.$emit('pick');
       },
 
       resetDate() {

+ 1 - 1
packages/date-picker/src/panel/time-select.vue

@@ -85,7 +85,7 @@
       },
 
       handleClear() {
-        this.$emit('pick', '');
+        this.$emit('pick');
       }
     },
 

+ 1 - 1
packages/date-picker/src/panel/time.vue

@@ -104,7 +104,7 @@
 
     methods: {
       handleClear() {
-        this.$emit('pick', '');
+        this.$emit('pick');
       },
 
       handleCancel() {

+ 23 - 5
packages/date-picker/src/picker.vue

@@ -26,7 +26,7 @@
 <script>
 import Vue from 'vue';
 import Clickoutside from 'element-ui/src/utils/clickoutside';
-import { formatDate, parseDate, getWeekNumber } from './util';
+import { formatDate, parseDate, getWeekNumber, equalDate } from './util';
 import Popper from 'element-ui/src/utils/vue-popper';
 import Emitter from 'element-ui/src/mixins/emitter';
 import ElInput from 'element-ui/packages/input';
@@ -309,9 +309,10 @@ export default {
           if (parsedValue && this.picker) {
             this.picker.value = parsedValue;
           }
-          return;
+        } else {
+          this.picker.value = value;
         }
-        this.picker.value = value;
+        this.$forceUpdate();
       }
     }
   },
@@ -337,12 +338,27 @@ export default {
       if (this.readonly || this.disabled) return;
       if (this.showClose) {
         this.internalValue = '';
-        this.$emit('input', '');
       } else {
         this.pickerVisible = !this.pickerVisible;
       }
     },
 
+    dateIsUpdated(date) {
+      let updated = true;
+
+      if (Array.isArray(date)) {
+        if (equalDate(this.cacheDateMin, date[0]) &&
+          equalDate(this.cacheDateMax, date[1])) updated = false;
+        this.cacheDateMin = date[0];
+        this.cacheDateMax = date[1];
+      } else {
+        if (equalDate(this.cacheDate, date)) updated = false;
+        this.cacheDate = date;
+      }
+
+      return updated;
+    },
+
     handleClose() {
       this.pickerVisible = false;
     },
@@ -422,7 +438,9 @@ export default {
 
         this.picker.$on('dodestroy', this.doDestroy);
         this.picker.$on('pick', (date, visible = false) => {
-          this.$emit('input', date);
+          if (this.dateIsUpdated(date)) this.$emit('input', date);
+
+          this.$nextTick(() => this.$emit('change', this.visualValue));
           this.pickerVisible = this.picker.visible = visible;
           this.picker.resetView && this.picker.resetView();
         });

+ 4 - 0
packages/date-picker/src/util/index.js

@@ -8,6 +8,10 @@ const newArray = function(start, end) {
   return result;
 };
 
+export const equalDate = function(dateA, dateB) {
+  return new Date(dateA).getTime() === new Date(dateB).getTime();
+};
+
 export const toDate = function(date) {
   date = new Date(date);
   if (isNaN(date.getTime())) return null;

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

@@ -145,6 +145,46 @@ describe('DatePicker', () => {
     }, DELAY);
   });
 
+  it('change event', done => {
+    let inputValue;
+
+    vm = createVue({
+      template: `
+        <el-date-picker
+          ref="compo"
+          v-model="value"
+          format="yyyy-MM"
+          @change="handleChange" />`,
+
+      methods: {
+        handleChange(val) {
+          inputValue = val;
+        }
+      },
+
+      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();
+      vm.$nextTick(_ => {
+        const date = picker.date;
+
+        expect(inputValue).to.equal(`${date.getFullYear()}-${date.getMonth() + 1 }`);
+        done();
+      });
+    }, DELAY);
+  });
+
   describe('keydown', () => {
     let input;
     let keyDown = function(el, keyCode) {