Browse Source

Radio: change event only triggers on user input

Leopoldthecoder 8 years ago
parent
commit
22ab137963

+ 8 - 2
examples/docs/en-US/radio.md

@@ -137,6 +137,12 @@ label | the value of radio | string/number/boolean | — | —
 disabled | whether radio is disabled | boolean | — | false
 name | native 'name' attribute | string    |      —         |     —
 
+### Radio Events
+
+| Event Name | Description | Parameters |
+| --- | --- | --- |
+| change | triggers when the bound value changes | the label value of the chosen radio |
+
 ### Radio-group Attributes
 
  Attribute      | Description          | Type      | Accepted Values       | Default
@@ -148,8 +154,8 @@ text-color | font color when button is active | string   | — | #ffffff   |
 ### Radio-group Events
 
 | Event Name | Description | Parameters |
---- | --- | ---
-change | triggers when the bound value changes | the label value of the chosen radio
+| --- | --- | --- |
+| change | triggers when the bound value changes | the label value of the chosen radio |
 
 ### Radio-button Attributes
 

+ 5 - 0
examples/docs/zh-CN/radio.md

@@ -141,6 +141,11 @@
 | disabled  | 是否禁用    | boolean   | — | false   |
 | name | 原生 name 属性 | string    |      —         |     —    |
 
+### Radio Events
+| 事件名称 | 说明 | 回调参数 |
+|---------- |-------- |---------- |
+| change  | 绑定值变化时触发的事件 |  选中的 Radio label 值  |
+
 ### Radio-group Attributes
 | 参数      | 说明    | 类型      | 可选值       | 默认值   |
 |---------- |-------- |---------- |-------------  |-------- |

+ 13 - 0
packages/radio/src/radio-button.vue

@@ -18,6 +18,7 @@
       type="radio"
       v-model="value"
       :name="name"
+      @change="handleChange"
       :disabled="isDisabled"
       tabindex="-1"
     >
@@ -28,9 +29,13 @@
   </label>
 </template>
 <script>
+  import Emitter from 'element-ui/src/mixins/emitter';
+
   export default {
     name: 'ElRadioButton',
 
+    mixins: [Emitter],
+
     props: {
       label: {},
       disabled: Boolean,
@@ -73,6 +78,14 @@
       tabIndex() {
         return !this.isDisabled ? (this._radioGroup ? (this.value === this.label ? 0 : -1) : 0) : -1;
       }
+    },
+
+    methods: {
+      handleChange() {
+        this.$nextTick(() => {
+          this.dispatch('ElRadioGroup', 'handleChange', this.value);
+        });
+      }
     }
   };
 </script>

+ 5 - 1
packages/radio/src/radio-group.vue

@@ -30,6 +30,11 @@
       textColor: String,
       disabled: Boolean
     },
+    created() {
+      this.$on('handleChange', value => {
+        this.$emit('change', value);
+      });
+    },
     mounted() {
       // 当radioGroup没有默认选项时,第一个可以选中Tab导航
       let radios = this.$el.querySelectorAll('[type=radio]');
@@ -73,7 +78,6 @@
     },
     watch: {
       value(value) {
-        this.$emit('change', value);
         this.dispatch('ElFormItem', 'el.form.change', [this.value]);
       }
     }

+ 10 - 0
packages/radio/src/radio.vue

@@ -22,6 +22,7 @@
         v-model="model"
         @focus="focus = true"
         @blur="focus = false"
+        @change="handleChange"
         :name="name"
         :disabled="isDisabled"
         tabindex="-1"
@@ -89,6 +90,15 @@
       tabIndex() {
         return !this.isDisabled ? (this.isGroup ? (this.model === this.label ? 0 : -1) : 0) : -1;
       }
+    },
+
+    methods: {
+      handleChange() {
+        this.$nextTick(() => {
+          this.$emit('change', this.model);
+          this.isGroup && this.dispatch('ElRadioGroup', 'handleChange', this.model);
+        });
+      }
     }
   };
 </script>

+ 167 - 0
test/unit/specs/radio.spec.js

@@ -50,6 +50,63 @@ describe('Radio', () => {
       done();
     });
   });
+  it('change event', done => {
+    vm = createVue({
+      template: `
+        <el-radio
+          v-model="radio"
+          label="3"
+          @change="handleChange"
+        >
+        </el-radio>
+      `,
+      data() {
+        return {
+          radio: '',
+          data: ''
+        };
+      },
+      methods: {
+        handleChange(val) {
+          this.data = val;
+        }
+      }
+    }, true);
+    let radioElm = vm.$el;
+    radioElm.click();
+    setTimeout(_ => {
+      expect(vm.data).to.equal('3');
+      done();
+    }, 10);
+  });
+  it('change event only triggers on user input', done => {
+    vm = createVue({
+      template: `
+        <el-radio
+          v-model="radio"
+          label="3"
+          @change="handleChange"
+        >
+        </el-radio>
+      `,
+      data() {
+        return {
+          radio: '',
+          data: ''
+        };
+      },
+      methods: {
+        handleChange(val) {
+          this.data = val;
+        }
+      }
+    }, true);
+    vm.radio = '3';
+    setTimeout(_ => {
+      expect(vm.data).to.equal('');
+      done();
+    }, 10);
+  });
   describe('Radio group', () => {
     it('create', done => {
       vm = createVue({
@@ -102,6 +159,61 @@ describe('Radio', () => {
         done();
       });
     });
+    it('change event', done => {
+      vm = createVue({
+        template: `
+          <el-radio-group v-model="radio" @change="onChange">
+            <el-radio :label="3">备选项</el-radio>
+            <el-radio :label="6" ref="radio2">备选项</el-radio>
+            <el-radio :label="9">备选项</el-radio>
+          </el-radio-group>
+        `,
+        methods: {
+          onChange(val) {
+            this.data = val;
+          }
+        },
+        data() {
+          return {
+            radio: 3,
+            data: 0
+          };
+        }
+      }, true);
+      let radio2 = vm.$refs.radio2;
+      radio2.$el.click();
+      setTimeout(_ => {
+        expect(vm.data).to.equal(6);
+        done();
+      }, 10);
+    });
+    it('change event only triggers on user input', done => {
+      vm = createVue({
+        template: `
+          <el-radio-group v-model="radio" @change="onChange">
+            <el-radio :label="3">备选项</el-radio>
+            <el-radio :label="6">备选项</el-radio>
+            <el-radio :label="9">备选项</el-radio>
+          </el-radio-group>
+        `,
+        methods: {
+          onChange(val) {
+            this.data = val;
+          }
+        },
+        data() {
+          return {
+            radio: 3,
+            data: 0
+          };
+        }
+      }, true);
+      vm.radio = 6;
+      setTimeout(_ => {
+        expect(vm.data).to.equal(0);
+        done();
+      }, 10);
+    });
     it('disabled when children is radio button', done => {
       vm = createVue({
         template: `
@@ -174,6 +286,61 @@ describe('Radio', () => {
           done();
         });
       });
+      it('change event', done => {
+        vm = createVue({
+          template: `
+            <el-radio-group v-model="radio" @change="onChange">
+              <el-radio-button :label="3">备选项</el-radio-button>
+              <el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
+              <el-radio-button :label="9">备选项</el-radio-button>
+            </el-radio-group>
+          `,
+          methods: {
+            onChange(val) {
+              this.data = val;
+            }
+          },
+          data() {
+            return {
+              data: 0,
+              radio: 3
+            };
+          }
+        }, true);
+        let radio = vm.$refs.radio2;
+        radio.$el.click();
+        setTimeout(_ => {
+          expect(vm.data).to.equal(6);
+          done();
+        }, 10);
+      });
+      it('change event only triggers on user input', done => {
+        vm = createVue({
+          template: `
+            <el-radio-group v-model="radio" @change="onChange">
+              <el-radio-button :label="3">备选项</el-radio-button>
+              <el-radio-button :label="6" ref="radio2">备选项</el-radio-button>
+              <el-radio-button :label="9">备选项</el-radio-button>
+            </el-radio-group>
+          `,
+          methods: {
+            onChange(val) {
+              this.data = val;
+            }
+          },
+          data() {
+            return {
+              data: 0,
+              radio: 3
+            };
+          }
+        }, true);
+        vm.radio = 6;
+        setTimeout(_ => {
+          expect(vm.data).to.equal(0);
+          done();
+        }, 10);
+      });
       it('size', done => {
         vm = createVue({
           template: `