Jelajahi Sumber

support focus and blur event for some form component

Dreamacro 8 tahun lalu
induk
melakukan
c1829e69f1

+ 2 - 0
examples/docs/en-US/date-picker.md

@@ -307,3 +307,5 @@ Picking a date range is supported.
 | Event Name | Description | Parameters |
 |---------|--------|---------|
 | change | triggers when input value changes | formatted value |
+| blur | triggers when input is blur | (event: Event) |
+| focus | triggers when input is focus | (event: Event) |

+ 2 - 2
examples/docs/en-US/datetime-picker.md

@@ -254,9 +254,9 @@ 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 |
-
+| blur | triggers when input is blur | (event: Event) |
+| focus | triggers when input is focus | (event: Event) |

+ 3 - 1
examples/docs/en-US/input-number.md

@@ -140,4 +140,6 @@ Additional `large` and `small` sizes of the input box are available
 
 | Event Name | Description | Parameters |
 |----| ---- | -----|
-|change | triggers when the value changes | value after change |
+|change | triggers when the value changes | value after change |
+| blur | triggers when the icon inside Input is blur | (event: Event) |
+| focus | triggers when the icon inside Input is focus | (event: Event) |

+ 2 - 1
examples/docs/en-US/time-picker.md

@@ -182,4 +182,5 @@ Can pick an arbitrary time range.
 | Event Name | Description | Parameters |
 |---------|--------|---------|
 | change | triggers when input value changes | formatted value |
-
+| blur | triggers when input is blur | (event: Event) |
+| focus | triggers when input is focus | (event: Event) |

+ 2 - 1
examples/docs/zh-CN/date-picker.md

@@ -316,4 +316,5 @@
 | 事件名称      | 说明    | 回调参数      |
 |---------|--------|---------|
 | change | 当 input 的值改变时触发,返回值和文本框一致 | 格式化后的值 |
-
+| blur | 当 input 失去焦点时触发 | (event: Event) |
+| focus | 当 input 获得焦点时触发 | (event: Event) |

+ 2 - 3
examples/docs/zh-CN/datetime-picker.md

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

+ 2 - 0
examples/docs/zh-CN/input-number.md

@@ -137,3 +137,5 @@
 | 事件名称 | 说明 | 回调参数 |
 |---------|--------|---------|
 | change | 绑定值被改变时触发 | 最后变更的值 |
+| blur | 在组件 Input 失去焦点时触发 | (event: Event) |
+| focus | 在组件 Input 获得焦点时触发 | (event: Event) |

+ 2 - 4
examples/docs/zh-CN/time-picker.md

@@ -176,11 +176,9 @@
 | selectableRange | 可选时间段,例如`'18:30:00 - 20:30:00'`或者传入数组`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string/array | — | — |
 | format | 时间格式化(TimePicker) | string | 小时:`HH`,分:`mm`,秒:`ss` | 'HH:mm:ss' |
 
-
 ### Events
 | Event Name | Description | Parameters |
 |---------|--------|---------|
 | change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
-
-
-
+| blur | 当 input 失去焦点时触发 | (event: Event) |
+| focus | 当 input 获得焦点时触发 | (event: Event) |

+ 6 - 1
packages/autocomplete/src/autocomplete.vue

@@ -14,6 +14,7 @@
       @compositionend.native="handleComposition"
       @change="handleChange"
       @focus="handleFocus"
+      @blur="handleBlur"
       @keydown.up.native.prevent="highlight(highlightedIndex - 1)"
       @keydown.down.native.prevent="highlight(highlightedIndex + 1)"
       @keydown.enter.native.prevent="handleKeyEnter"
@@ -129,12 +130,16 @@
         }
         this.getData(value);
       },
-      handleFocus() {
+      handleFocus(event) {
         this.activated = true;
+        this.$emit('focus', event);
         if (this.triggerOnFocus) {
           this.getData(this.value);
         }
       },
+      handleBlur(event) {
+        this.$emit('blur', event);
+      },
       close(e) {
         this.activated = false;
       },

+ 6 - 1
packages/input-number/src/input-number.vue

@@ -27,6 +27,7 @@
       @keydown.up.native.prevent="increase"
       @keydown.down.native.prevent="decrease"
       @blur="handleBlur"
+      @focus="handleFocus"
       @input="debounceHandleInput"
       :disabled="disabled"
       :size="size"
@@ -175,9 +176,13 @@
         if (newVal < this.min) return;
         this.setCurrentValue(newVal);
       },
-      handleBlur() {
+      handleBlur(event) {
+        this.$emit('blur', event);
         this.$refs.input.setCurrentValue(this.currentValue);
       },
+      handleFocus(event) {
+        this.$emit('focus', event);
+      },
       setCurrentValue(newVal) {
         const oldVal = this.currentValue;
         if (newVal >= this.max) newVal = this.max;

+ 56 - 0
test/unit/specs/autocomplete.spec.js

@@ -384,4 +384,60 @@ describe('Autocomplete', () => {
       done();
     }, 500);
   });
+  it('event:focus & blur', done => {
+    vm = createVue({
+      template: `
+        <el-autocomplete
+          ref="input"
+          v-model="state"
+          :fetch-suggestions="querySearch"
+          :trigger-on-focus="false"
+          placeholder="请输入内容autocomplete1"
+        ></el-autocomplete>
+      `,
+      data() {
+        return {
+          restaurants: [],
+          state: ''
+        };
+      },
+      methods: {
+        querySearch(queryString, cb) {
+          var restaurants = this.restaurants;
+          var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
+          cb(results);
+        },
+        createFilter(queryString) {
+          return (restaurant) => {
+            return (restaurant.value.indexOf(queryString.toLowerCase()) === 0);
+          };
+        },
+        loadAll() {
+          return [
+            { 'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号' },
+            { 'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号' },
+            { 'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113' },
+            { 'value': '泷千家(天山西路店)', 'address': '天山西路438号' }
+          ];
+        }
+      },
+      mounted() {
+        this.restaurants = this.loadAll();
+      }
+    }, 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();
+    });
+  });
 });

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

@@ -316,6 +316,27 @@ describe('DatePicker', () => {
       }, DELAY);
     });
 
+    it('work for event focus and blur', done => {
+      vm = createVue({
+        template: `
+          <el-date-picker ref="picker"/>
+        `
+      }, true);
+
+      const spyFocus = sinon.spy();
+      const spyBlur = sinon.spy();
+
+      vm.$refs.picker.$on('focus', spyFocus);
+      vm.$refs.picker.$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('default value', done => {

+ 22 - 0
test/unit/specs/input-number.spec.js

@@ -289,4 +289,26 @@ describe('InputNumber', () => {
       done();
     });
   });
+  it('event:focus & blur', done => {
+    vm = createVue({
+      template: `
+        <el-input-number ref="input">
+        </el-input-number>
+      `
+    }, 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();
+    });
+  });
 });

+ 27 - 1
test/unit/specs/time-picker.spec.js

@@ -1,4 +1,4 @@
-import { createTest, destroyVM } from '../util';
+import { createTest, destroyVM, createVue } from '../util';
 import TimePicker from 'packages/time-picker';
 import Vue from 'vue';
 
@@ -176,6 +176,32 @@ describe('TimePicker', () => {
       done();
     }, 20);
   });
+
+  it('event focus and blur', done => {
+    vm = createVue({
+      template: `
+        <el-date-picker
+          type="date"
+          placeholder="选择日期"
+          ref="picker">
+        </el-date-picker>
+      `
+    }, true);
+
+    const spyFocus = sinon.spy();
+    const spyBlur = sinon.spy();
+
+    vm.$refs.picker.$on('focus', spyFocus);
+    vm.$refs.picker.$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();
+    });
+  });
 });
 
 describe('TimePicker(range)', () => {

+ 29 - 0
test/unit/specs/time-select.spec.js

@@ -198,4 +198,33 @@ describe('TimeSelect', () => {
     }, 50);
   });
 
+  it('event focus and blur', done => {
+    vm = createVue({
+      template: `
+        <el-time-select
+          ref="picker"
+          :picker-options="{
+            start: '08:30',
+            step: '00:15',
+            end: '18:30'
+          }"
+          placeholder="选择时间">
+        </el-time-select>
+      `
+    }, true);
+
+    const spyFocus = sinon.spy();
+    const spyBlur = sinon.spy();
+
+    vm.$refs.picker.$on('focus', spyFocus);
+    vm.$refs.picker.$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();
+    });
+  });
 });