Răsfoiți Sursa

Select: add multipleLimit

Leopoldthecoder 8 ani în urmă
părinte
comite
c058beb2be

+ 1 - 0
examples/docs/en-US/select.md

@@ -575,6 +575,7 @@ Enter keywords and search data from server.
 | multiple | whether multiple-select is activated | boolean | — | false |
 | disabled | whether Select is disabled | boolean | — | false |
 | clearable | whether single select can be cleared | boolean | — | false |
+| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | number | — | 0 |
 | name | the name attribute of select input | string | — | — |
 | placeholder | placeholder | string | — | Select |
 | filterable | whether Select is filterable | boolean | — | false |

+ 1 - 0
examples/docs/zh-CN/select.md

@@ -590,6 +590,7 @@
 | multiple | 是否多选 | boolean | — | false |
 | disabled | 是否禁用 | boolean | — | false |
 | clearable | 单选时是否可以清空选项 | boolean | — | false |
+| multiple-limit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number | — | 0 |
 | name | select input 的 name 属性 | string | — | — |
 | placeholder | 占位符 | string | — | 请选择 |
 | filterable | 是否可搜索 | boolean | — | false |

+ 11 - 1
packages/select/src/option.vue

@@ -6,7 +6,7 @@
     v-show="visible"
     :class="{
       'selected': itemSelected,
-      'is-disabled': disabled || groupDisabled,
+      'is-disabled': disabled || groupDisabled || limitReached,
       'hover': parent.hoverIndex === index
     }">
     <slot>
@@ -72,6 +72,16 @@
         } else {
           return this.parent.value.indexOf(this.value) > -1;
         }
+      },
+
+      limitReached() {
+        if (this.parent.multiple) {
+          return !this.itemSelected &&
+            this.parent.value.length >= this.parent.multipleLimit &&
+            this.parent.multipleLimit > 0;
+        } else {
+          return false;
+        }
       }
     },
 

+ 5 - 1
packages/select/src/select.vue

@@ -154,6 +154,10 @@
       remoteMethod: Function,
       filterMethod: Function,
       multiple: Boolean,
+      multipleLimit: {
+        type: Number,
+        default: 0
+      },
       placeholder: {
         type: String,
         default() {
@@ -398,7 +402,7 @@
           });
           if (optionIndex > -1) {
             this.value.splice(optionIndex, 1);
-          } else {
+          } else if (this.multipleLimit <= 0 || this.value.length < this.multipleLimit) {
             this.value.push(option.value);
           }
         }

+ 17 - 0
test/unit/specs/select.spec.js

@@ -6,6 +6,7 @@ describe('Select', () => {
     ['multiple', 'clearable', 'filterable', 'remote'].forEach(config => {
       configs[config] = configs[config] || false;
     });
+    configs.multipleLimit = configs.multipleLimit || 0;
     if (!options) {
       options = [{
         value: '选项1',
@@ -35,6 +36,7 @@ describe('Select', () => {
           <el-select
             v-model="value"
             :multiple="multiple"
+            :multiple-limit="multipleLimit"
             :clearable="clearable"
             :filterable="filterable"
             :filterMethod="filterMethod"
@@ -55,6 +57,7 @@ describe('Select', () => {
         return {
           options,
           multiple: configs.multiple,
+          multipleLimit: configs.multipleLimit,
           clearable: configs.clearable,
           filterable: configs.filterable,
           loading: false,
@@ -368,6 +371,20 @@ describe('Select', () => {
     }, 100);
   });
 
+  it('multiple limit', done => {
+    vm = getSelectVm({ multiple: true, multipleLimit: 1 });
+    const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
+    options[1].click();
+    setTimeout(() => {
+      expect(vm.value.indexOf('选项2') > -1).to.true;
+      options[3].click();
+      setTimeout(() => {
+        expect(vm.value.indexOf('选项4')).to.equal(-1);
+        done();
+      }, 50);
+    }, 50);
+  });
+
   it('multiple remote search', done => {
     const remoteMethod = vm => {
       return query => {