mirror of https://github.com/ElemeFE/element
Merge pull request #1401 from Leopoldthecoder/select-refactor
Select: refactor and bug fixpull/1402/merge
commit
d3afe22e89
|
@ -62,6 +62,16 @@
|
||||||
}]
|
}]
|
||||||
}],
|
}],
|
||||||
options4: [],
|
options4: [],
|
||||||
|
options5: [{
|
||||||
|
value: 'HTML',
|
||||||
|
label: 'HTML'
|
||||||
|
}, {
|
||||||
|
value: 'CSS',
|
||||||
|
label: 'CSS'
|
||||||
|
}, {
|
||||||
|
value: 'JavaScript',
|
||||||
|
label: 'JavaScript'
|
||||||
|
}],
|
||||||
cities: [{
|
cities: [{
|
||||||
value: 'Beijing',
|
value: 'Beijing',
|
||||||
label: 'Beijing'
|
label: 'Beijing'
|
||||||
|
@ -87,9 +97,10 @@
|
||||||
value4: '',
|
value4: '',
|
||||||
value5: [],
|
value5: [],
|
||||||
value6: '',
|
value6: '',
|
||||||
value7: [],
|
value7: '',
|
||||||
value8: '',
|
value8: '',
|
||||||
value9: [],
|
value9: [],
|
||||||
|
value10: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
states: ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"]
|
states: ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"]
|
||||||
};
|
};
|
||||||
|
@ -569,15 +580,58 @@ Enter keywords and search data from server.
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### Create new items
|
||||||
|
Create and select new items that are not included in select options
|
||||||
|
:::demo By using the `allow-create` attribute, users can create new items by typing in the input box. Note that for `allow-create` to work, `filterable` must be `true`.
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-select
|
||||||
|
v-model="value10"
|
||||||
|
multiple
|
||||||
|
filterable
|
||||||
|
allow-create
|
||||||
|
placeholder="Choose tags for your article">
|
||||||
|
<el-option
|
||||||
|
v-for="item in options5"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options5: [{
|
||||||
|
value: 'HTML',
|
||||||
|
label: 'HTML'
|
||||||
|
}, {
|
||||||
|
value: 'CSS',
|
||||||
|
label: 'CSS'
|
||||||
|
}, {
|
||||||
|
value: 'JavaScript',
|
||||||
|
label: 'JavaScript'
|
||||||
|
}],
|
||||||
|
value10: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Select Attributes
|
### Select Attributes
|
||||||
| Attribute | Description | Type | Accepted Values | Default |
|
| Attribute | Description | Type | Accepted Values | Default |
|
||||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||||
| multiple | whether multiple-select is activated | boolean | — | false |
|
| multiple | whether multiple-select is activated | boolean | — | false |
|
||||||
| disabled | whether Select is disabled | boolean | — | false |
|
| disabled | whether Select is disabled | boolean | — | false |
|
||||||
| clearable | whether single select can be cleared | 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 | — | — |
|
| name | the name attribute of select input | string | — | — |
|
||||||
| placeholder | placeholder | string | — | Select |
|
| placeholder | placeholder | string | — | Select |
|
||||||
| filterable | whether Select is filterable | boolean | — | false |
|
| filterable | whether Select is filterable | boolean | — | false |
|
||||||
|
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | boolean | — | false |
|
||||||
| filter-method | custom filter method | function | — | — |
|
| filter-method | custom filter method | function | — | — |
|
||||||
| remote | whether options are loaded from server | boolean | — | false |
|
| remote | whether options are loaded from server | boolean | — | false |
|
||||||
| remote-method | custom remote search method | function | — | — |
|
| remote-method | custom remote search method | function | — | — |
|
||||||
|
|
|
@ -62,6 +62,16 @@
|
||||||
}]
|
}]
|
||||||
}],
|
}],
|
||||||
options4: [],
|
options4: [],
|
||||||
|
options5: [{
|
||||||
|
value: 'HTML',
|
||||||
|
label: 'HTML'
|
||||||
|
}, {
|
||||||
|
value: 'CSS',
|
||||||
|
label: 'CSS'
|
||||||
|
}, {
|
||||||
|
value: 'JavaScript',
|
||||||
|
label: 'JavaScript'
|
||||||
|
}],
|
||||||
cities: [{
|
cities: [{
|
||||||
value: 'Beijing',
|
value: 'Beijing',
|
||||||
label: '北京'
|
label: '北京'
|
||||||
|
@ -87,9 +97,10 @@
|
||||||
value4: '',
|
value4: '',
|
||||||
value5: [],
|
value5: [],
|
||||||
value6: '',
|
value6: '',
|
||||||
value7: [],
|
value7: '',
|
||||||
value8: '',
|
value8: '',
|
||||||
value9: [],
|
value9: '',
|
||||||
|
value10: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
states: ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"]
|
states: ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"]
|
||||||
};
|
};
|
||||||
|
@ -129,7 +140,6 @@
|
||||||
### 基础用法
|
### 基础用法
|
||||||
|
|
||||||
适用广泛的基础单选
|
适用广泛的基础单选
|
||||||
|
|
||||||
:::demo `v-model`的值为当前被选中的`el-option`的 value 属性值
|
:::demo `v-model`的值为当前被选中的`el-option`的 value 属性值
|
||||||
```html
|
```html
|
||||||
<template>
|
<template>
|
||||||
|
@ -499,7 +509,6 @@
|
||||||
### 远程搜索
|
### 远程搜索
|
||||||
|
|
||||||
从服务器搜索数据,输入关键字进行查找
|
从服务器搜索数据,输入关键字进行查找
|
||||||
|
|
||||||
:::demo 为了启用远程搜索,需要将`filterable`和`remote`设置为`true`,同时传入一个`remote-method`。`remote-method`为一个`Function`,它会在输入值发生变化时调用,参数为当前输入值。需要注意的是,如果`el-option`是通过`v-for`指令渲染出来的,此时需要为`el-option`添加`key`属性,且其值需具有唯一性,比如此例中的`item.value`。
|
:::demo 为了启用远程搜索,需要将`filterable`和`remote`设置为`true`,同时传入一个`remote-method`。`remote-method`为一个`Function`,它会在输入值发生变化时调用,参数为当前输入值。需要注意的是,如果`el-option`是通过`v-for`指令渲染出来的,此时需要为`el-option`添加`key`属性,且其值需具有唯一性,比如此例中的`item.value`。
|
||||||
```html
|
```html
|
||||||
<template>
|
<template>
|
||||||
|
@ -573,15 +582,58 @@
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### 创建条目
|
||||||
|
可以创建并选中选项中不存在的条目
|
||||||
|
:::demo 使用`allow-create`属性即可通过在输入框中输入文字来创建新的条目。注意此时`filterable`必须为真。
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-select
|
||||||
|
v-model="value10"
|
||||||
|
multiple
|
||||||
|
filterable
|
||||||
|
allow-create
|
||||||
|
placeholder="请选择文章标签">
|
||||||
|
<el-option
|
||||||
|
v-for="item in options5"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options5: [{
|
||||||
|
value: 'HTML',
|
||||||
|
label: 'HTML'
|
||||||
|
}, {
|
||||||
|
value: 'CSS',
|
||||||
|
label: 'CSS'
|
||||||
|
}, {
|
||||||
|
value: 'JavaScript',
|
||||||
|
label: 'JavaScript'
|
||||||
|
}],
|
||||||
|
value10: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Select Attributes
|
### Select Attributes
|
||||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||||
| multiple | 是否多选 | boolean | — | false |
|
| multiple | 是否多选 | boolean | — | false |
|
||||||
| disabled | 是否禁用 | boolean | — | false |
|
| disabled | 是否禁用 | boolean | — | false |
|
||||||
| clearable | 单选时是否可以清空选项 | boolean | — | false |
|
| clearable | 单选时是否可以清空选项 | boolean | — | false |
|
||||||
|
| multiple-limit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number | — | 0 |
|
||||||
| name | select input 的 name 属性 | string | — | — |
|
| name | select input 的 name 属性 | string | — | — |
|
||||||
| placeholder | 占位符 | string | — | 请选择 |
|
| placeholder | 占位符 | string | — | 请选择 |
|
||||||
| filterable | 是否可搜索 | boolean | — | false |
|
| filterable | 是否可搜索 | boolean | — | false |
|
||||||
|
| allow-create | 是否允许用户创建新条目,需配合 `filterable` 使用 | boolean | — | false |
|
||||||
| filter-method | 自定义过滤方法 | function | — | — |
|
| filter-method | 自定义过滤方法 | function | — | — |
|
||||||
| remote | 是否为远程搜索 | boolean | — | false |
|
| remote | 是否为远程搜索 | boolean | — | false |
|
||||||
| remote-method | 远程搜索方法 | function | — | — |
|
| remote-method | 远程搜索方法 | function | — | — |
|
||||||
|
|
|
@ -140,10 +140,8 @@ export default {
|
||||||
return (
|
return (
|
||||||
<span class="el-pagination__sizes">
|
<span class="el-pagination__sizes">
|
||||||
<el-select
|
<el-select
|
||||||
size="small"
|
|
||||||
value={ this.$parent.internalPageSize }
|
value={ this.$parent.internalPageSize }
|
||||||
on-change={ this.handleChange }
|
on-input={ this.handleChange }>
|
||||||
width={ 110 }>
|
|
||||||
{
|
{
|
||||||
this.pageSizes.map(item =>
|
this.pageSizes.map(item =>
|
||||||
<el-option
|
<el-option
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
@click.stop="selectOptionClick"
|
@click.stop="selectOptionClick"
|
||||||
class="el-select-dropdown__item"
|
class="el-select-dropdown__item"
|
||||||
v-show="visible"
|
v-show="visible"
|
||||||
:class="{ 'selected': itemSelected, 'is-disabled': disabled || groupDisabled, 'hover': parent.hoverIndex === index }">
|
:class="{
|
||||||
|
'selected': itemSelected,
|
||||||
|
'is-disabled': disabled || groupDisabled || limitReached,
|
||||||
|
'hover': parent.hoverIndex === index
|
||||||
|
}">
|
||||||
<slot>
|
<slot>
|
||||||
<span>{{ currentLabel }}</span>
|
<span>{{ currentLabel }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
|
@ -30,6 +34,7 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
created: Boolean,
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
@ -63,22 +68,20 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
itemSelected() {
|
itemSelected() {
|
||||||
if (Object.prototype.toString.call(this.parent.selected) === '[object Object]') {
|
if (!this.parent.multiple) {
|
||||||
return this === this.parent.selected;
|
return this.value === this.parent.value;
|
||||||
} else if (Array.isArray(this.parent.selected)) {
|
} else {
|
||||||
return this.parent.value.indexOf(this.value) > -1;
|
return this.parent.value.indexOf(this.value) > -1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
currentSelected() {
|
limitReached() {
|
||||||
return this.selected || (this.parent.multiple ? this.parent.value.indexOf(this.value) > -1 : this.parent.value === this.value);
|
if (this.parent.multiple) {
|
||||||
}
|
return !this.itemSelected &&
|
||||||
},
|
this.parent.value.length >= this.parent.multipleLimit &&
|
||||||
|
this.parent.multipleLimit > 0;
|
||||||
watch: {
|
} else {
|
||||||
currentSelected(val) {
|
return false;
|
||||||
if (val === true) {
|
|
||||||
this.dispatch('ElSelect', 'addOptionToValue', this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -103,7 +106,7 @@
|
||||||
queryChange(query) {
|
queryChange(query) {
|
||||||
// query 里如果有正则中的特殊字符,需要先将这些字符转义
|
// query 里如果有正则中的特殊字符,需要先将这些字符转义
|
||||||
let parsedQuery = query.replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
|
let parsedQuery = query.replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
|
||||||
this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel);
|
this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel) || this.created;
|
||||||
if (!this.visible) {
|
if (!this.visible) {
|
||||||
this.parent.filteredOptionsCount--;
|
this.parent.filteredOptionsCount--;
|
||||||
}
|
}
|
||||||
|
@ -122,10 +125,6 @@
|
||||||
this.parent.filteredOptionsCount++;
|
this.parent.filteredOptionsCount++;
|
||||||
this.index = this.parent.options.indexOf(this);
|
this.index = this.parent.options.indexOf(this);
|
||||||
|
|
||||||
if (this.currentSelected === true) {
|
|
||||||
this.dispatch('ElSelect', 'addOptionToValue', [this, true]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$on('queryChange', this.queryChange);
|
this.$on('queryChange', this.queryChange);
|
||||||
this.$on('handleGroupDisabled', this.handleGroupDisabled);
|
this.$on('handleGroupDisabled', this.handleGroupDisabled);
|
||||||
this.$on('resetIndex', this.resetIndex);
|
this.$on('resetIndex', this.resetIndex);
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="el-select"
|
class="el-select"
|
||||||
v-clickoutside="handleClose"
|
v-clickoutside="handleClose">
|
||||||
:class="{ 'is-multiple': multiple, 'is-small': size === 'small' }">
|
<div
|
||||||
<div class="el-select__tags" v-if="multiple" @click.stop="toggleMenu" ref="tags" :style="{ 'max-width': inputWidth - 32 + 'px' }">
|
class="el-select__tags"
|
||||||
|
v-if="multiple"
|
||||||
|
@click.stop="toggleMenu"
|
||||||
|
ref="tags"
|
||||||
|
:style="{ 'max-width': inputWidth - 32 + 'px' }">
|
||||||
<transition-group @after-leave="resetInputHeight">
|
<transition-group @after-leave="resetInputHeight">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="item in selected"
|
v-for="item in selected"
|
||||||
:key="item"
|
:key="item.value"
|
||||||
closable
|
closable
|
||||||
:hit="item.hitState"
|
:hit="item.hitState"
|
||||||
type="primary"
|
type="primary"
|
||||||
@close="deleteTag($event, item)"
|
@close="deleteTag($event, item)"
|
||||||
close-transition>{{ item.currentLabel }}</el-tag>
|
close-transition>
|
||||||
|
{{ item.currentLabel }}
|
||||||
|
</el-tag>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="el-select__input"
|
class="el-select__input"
|
||||||
|
@ -40,7 +47,7 @@
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:readonly="!filterable || multiple"
|
:readonly="!filterable || multiple"
|
||||||
@focus="toggleMenu"
|
@focus="toggleMenu"
|
||||||
@click="toggleMenu"
|
@click="handleIconClick"
|
||||||
@mousedown.native="handleMouseDown"
|
@mousedown.native="handleMouseDown"
|
||||||
@keyup.native="debouncedOnInputChange"
|
@keyup.native="debouncedOnInputChange"
|
||||||
@keydown.native.down.prevent="navigateOptions('next')"
|
@keydown.native.down.prevent="navigateOptions('next')"
|
||||||
|
@ -56,10 +63,18 @@
|
||||||
<el-select-menu
|
<el-select-menu
|
||||||
ref="popper"
|
ref="popper"
|
||||||
v-show="visible && emptyText !== false">
|
v-show="visible && emptyText !== false">
|
||||||
<ul class="el-select-dropdown__list" v-show="options.length > 0 && filteredOptionsCount > 0 && !loading">
|
<ul
|
||||||
|
class="el-select-dropdown__list"
|
||||||
|
:class="{ 'is-empty': !allowCreate && filteredOptionsCount === 0 }"
|
||||||
|
v-show="options.length > 0 && !loading">
|
||||||
|
<el-option
|
||||||
|
:value="query"
|
||||||
|
created
|
||||||
|
v-if="showNewOption">
|
||||||
|
</el-option>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="el-select-dropdown__empty" v-if="emptyText">{{ emptyText }}</p>
|
<p class="el-select-dropdown__empty" v-if="emptyText && !allowCreate">{{ emptyText }}</p>
|
||||||
</el-select-menu>
|
</el-select-menu>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -70,6 +85,7 @@
|
||||||
import Locale from 'element-ui/src/mixins/locale';
|
import Locale from 'element-ui/src/mixins/locale';
|
||||||
import ElInput from 'element-ui/packages/input';
|
import ElInput from 'element-ui/packages/input';
|
||||||
import ElSelectMenu from './select-dropdown.vue';
|
import ElSelectMenu from './select-dropdown.vue';
|
||||||
|
import ElOption from './option.vue';
|
||||||
import ElTag from 'element-ui/packages/tag';
|
import ElTag from 'element-ui/packages/tag';
|
||||||
import debounce from 'throttle-debounce/debounce';
|
import debounce from 'throttle-debounce/debounce';
|
||||||
import Clickoutside from 'element-ui/src/utils/clickoutside';
|
import Clickoutside from 'element-ui/src/utils/clickoutside';
|
||||||
|
@ -94,22 +110,18 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
showCloseIcon() {
|
showCloseIcon() {
|
||||||
let criteria = this.clearable && this.inputHovering && !this.multiple && this.options.indexOf(this.selected) > -1;
|
let criteria = this.clearable &&
|
||||||
|
this.inputHovering &&
|
||||||
|
!this.multiple &&
|
||||||
|
this.value !== undefined &&
|
||||||
|
this.value !== '';
|
||||||
if (!this.$el) return false;
|
if (!this.$el) return false;
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
let icon = this.$el.querySelector('.el-input__icon');
|
let icon = this.$el.querySelector('.el-input__icon');
|
||||||
if (icon) {
|
if (icon) {
|
||||||
if (criteria) {
|
criteria ? addClass(icon, 'is-show-close') : removeClass(icon, 'is-show-close');
|
||||||
icon.addEventListener('click', this.deleteSelected);
|
|
||||||
addClass(icon, 'is-show-close');
|
|
||||||
} else {
|
|
||||||
icon.removeEventListener('click', this.deleteSelected);
|
|
||||||
removeClass(icon, 'is-show-close');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return criteria;
|
return criteria;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -129,12 +141,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
showNewOption() {
|
||||||
|
let hasExistingOption = this.options.filter(option => !option.created)
|
||||||
|
.some(option => option.currentLabel === this.query);
|
||||||
|
return this.filterable && this.allowCreate && this.query !== '' && !hasExistingOption;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
ElInput,
|
ElInput,
|
||||||
ElSelectMenu,
|
ElSelectMenu,
|
||||||
|
ElOption,
|
||||||
ElTag
|
ElTag
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -143,15 +162,19 @@
|
||||||
props: {
|
props: {
|
||||||
name: String,
|
name: String,
|
||||||
value: {},
|
value: {},
|
||||||
size: String,
|
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
clearable: Boolean,
|
clearable: Boolean,
|
||||||
filterable: Boolean,
|
filterable: Boolean,
|
||||||
|
allowCreate: Boolean,
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
remote: Boolean,
|
remote: Boolean,
|
||||||
remoteMethod: Function,
|
remoteMethod: Function,
|
||||||
filterMethod: Function,
|
filterMethod: Function,
|
||||||
multiple: Boolean,
|
multiple: Boolean,
|
||||||
|
multipleLimit: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default() {
|
default() {
|
||||||
|
@ -163,22 +186,21 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
options: [],
|
options: [],
|
||||||
selected: {},
|
selected: this.multiple ? [] : {},
|
||||||
isSelect: true,
|
isSelect: true,
|
||||||
inputLength: 20,
|
inputLength: 20,
|
||||||
inputWidth: 0,
|
inputWidth: 0,
|
||||||
valueChangeBySelected: false,
|
|
||||||
cachedPlaceHolder: '',
|
cachedPlaceHolder: '',
|
||||||
optionsCount: 0,
|
optionsCount: 0,
|
||||||
filteredOptionsCount: 0,
|
filteredOptionsCount: 0,
|
||||||
dropdownUl: null,
|
dropdownUl: null,
|
||||||
visible: false,
|
visible: false,
|
||||||
selectedLabel: '',
|
selectedLabel: '',
|
||||||
selectInit: false,
|
|
||||||
hoverIndex: -1,
|
hoverIndex: -1,
|
||||||
query: '',
|
query: '',
|
||||||
voidRemoteQuery: false,
|
voidRemoteQuery: false,
|
||||||
bottomOverflowBeforeHidden: 0,
|
bottomOverflowBeforeHidden: 0,
|
||||||
|
topOverflowBeforeHidden: 0,
|
||||||
optionsAllDisabled: false,
|
optionsAllDisabled: false,
|
||||||
inputHovering: false,
|
inputHovering: false,
|
||||||
currentPlaceholder: ''
|
currentPlaceholder: ''
|
||||||
|
@ -191,79 +213,25 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
value(val) {
|
value(val) {
|
||||||
if (this.valueChangeBySelected) {
|
|
||||||
this.valueChangeBySelected = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.multiple && Array.isArray(val)) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.resetInputHeight();
|
|
||||||
});
|
|
||||||
this.selectedInit = true;
|
|
||||||
this.selected = [];
|
|
||||||
this.currentPlaceholder = this.cachedPlaceHolder;
|
|
||||||
val.forEach(item => {
|
|
||||||
let option = this.options.filter(option => option.value === item)[0];
|
|
||||||
if (option) {
|
|
||||||
this.$emit('addOptionToValue', option);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!this.multiple) {
|
|
||||||
let option = this.options.filter(option => option.value === val)[0];
|
|
||||||
if (option) {
|
|
||||||
this.$emit('addOptionToValue', option);
|
|
||||||
} else {
|
|
||||||
this.selected = {};
|
|
||||||
this.selectedLabel = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.resetHoverIndex();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
selected(val, oldVal) {
|
|
||||||
if (this.multiple) {
|
if (this.multiple) {
|
||||||
if (this.selected.length > 0) {
|
this.resetInputHeight();
|
||||||
|
if (val.length > 0) {
|
||||||
this.currentPlaceholder = '';
|
this.currentPlaceholder = '';
|
||||||
} else {
|
} else {
|
||||||
this.currentPlaceholder = this.cachedPlaceHolder;
|
this.currentPlaceholder = this.cachedPlaceHolder;
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
|
||||||
this.resetInputHeight();
|
|
||||||
});
|
|
||||||
if (this.selectedInit) {
|
|
||||||
this.selectedInit = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.valueChangeBySelected = true;
|
this.selected = this.getSelected();
|
||||||
const result = val.map(item => item.value);
|
if (this.filterable && !this.multiple) {
|
||||||
|
|
||||||
this.$emit('input', result);
|
|
||||||
this.$emit('change', result);
|
|
||||||
this.dispatch('ElFormItem', 'el.form.change', val);
|
|
||||||
if (this.filterable) {
|
|
||||||
this.query = '';
|
|
||||||
this.hoverIndex = -1;
|
|
||||||
this.$refs.input.focus();
|
|
||||||
this.inputLength = 20;
|
this.inputLength = 20;
|
||||||
}
|
}
|
||||||
} else {
|
this.$emit('change', val);
|
||||||
if (this.selectedInit) {
|
this.dispatch('ElFormItem', 'el.form.change', val);
|
||||||
this.selectedInit = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (val.value === oldVal.value) return;
|
|
||||||
this.$emit('input', val.value);
|
|
||||||
this.$emit('change', val.value);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
query(val) {
|
query(val) {
|
||||||
this.$nextTick(() => {
|
|
||||||
this.broadcast('ElSelectDropdown', 'updatePopper');
|
this.broadcast('ElSelectDropdown', 'updatePopper');
|
||||||
});
|
this.hoverIndex = -1;
|
||||||
if (this.multiple && this.filterable) {
|
if (this.multiple && this.filterable) {
|
||||||
this.resetInputHeight();
|
this.resetInputHeight();
|
||||||
}
|
}
|
||||||
|
@ -283,27 +251,22 @@
|
||||||
visible(val) {
|
visible(val) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
this.$refs.reference.$el.querySelector('input').blur();
|
this.$refs.reference.$el.querySelector('input').blur();
|
||||||
if (this.$el.querySelector('.el-input__icon')) {
|
this.handleIconHide();
|
||||||
removeClass(this.$el.querySelector('.el-input__icon'), 'is-reverse');
|
|
||||||
}
|
|
||||||
this.broadcast('ElSelectDropdown', 'destroyPopper');
|
this.broadcast('ElSelectDropdown', 'destroyPopper');
|
||||||
if (this.$refs.input) {
|
if (this.$refs.input) {
|
||||||
this.$refs.input.blur();
|
this.$refs.input.blur();
|
||||||
}
|
}
|
||||||
|
this.query = '';
|
||||||
|
this.selectedLabel = '';
|
||||||
this.resetHoverIndex();
|
this.resetHoverIndex();
|
||||||
if (!this.multiple) {
|
if (!this.multiple) {
|
||||||
if (this.dropdownUl && this.selected.$el) {
|
this.getOverflows();
|
||||||
this.bottomOverflowBeforeHidden = this.selected.$el.getBoundingClientRect().bottom - this.$refs.popper.$el.getBoundingClientRect().bottom;
|
|
||||||
}
|
|
||||||
if (this.selected && this.selected.value) {
|
if (this.selected && this.selected.value) {
|
||||||
this.selectedLabel = this.selected.currentLabel;
|
this.selectedLabel = this.selected.currentLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let icon = this.$el.querySelector('.el-input__icon');
|
this.handleIconShow();
|
||||||
if (icon && !hasClass(icon, 'el-icon-circle-close')) {
|
|
||||||
addClass(this.$el.querySelector('.el-input__icon'), 'is-reverse');
|
|
||||||
}
|
|
||||||
this.broadcast('ElSelectDropdown', 'updatePopper');
|
this.broadcast('ElSelectDropdown', 'updatePopper');
|
||||||
if (this.filterable) {
|
if (this.filterable) {
|
||||||
this.query = this.selectedLabel;
|
this.query = this.selectedLabel;
|
||||||
|
@ -318,19 +281,88 @@
|
||||||
this.dropdownUl = [].filter.call(dropdownChildNodes, item => item.tagName === 'UL')[0];
|
this.dropdownUl = [].filter.call(dropdownChildNodes, item => item.tagName === 'UL')[0];
|
||||||
}
|
}
|
||||||
if (!this.multiple && this.dropdownUl) {
|
if (!this.multiple && this.dropdownUl) {
|
||||||
if (this.bottomOverflowBeforeHidden > 0) {
|
this.setOverflow();
|
||||||
this.dropdownUl.scrollTop += this.bottomOverflowBeforeHidden;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
options(val) {
|
options(val) {
|
||||||
this.optionsAllDisabled = val.length === val.filter(item => item.disabled === true).length;
|
this.optionsAllDisabled = val.length === val.filter(item => item.disabled === true).length;
|
||||||
|
if (this.multiple) {
|
||||||
|
this.resetInputHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
handleIconHide() {
|
||||||
|
let icon = this.$el.querySelector('.el-input__icon');
|
||||||
|
if (icon) {
|
||||||
|
removeClass(icon, 'is-reverse');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleIconShow() {
|
||||||
|
let icon = this.$el.querySelector('.el-input__icon');
|
||||||
|
if (icon && !hasClass(icon, 'el-icon-circle-close')) {
|
||||||
|
addClass(icon, 'is-reverse');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getOverflows() {
|
||||||
|
if (this.dropdownUl && this.selected && this.selected.$el) {
|
||||||
|
let selectedRect = this.selected.$el.getBoundingClientRect();
|
||||||
|
let popperRect = this.$refs.popper.$el.getBoundingClientRect();
|
||||||
|
this.bottomOverflowBeforeHidden = selectedRect.bottom - popperRect.bottom;
|
||||||
|
this.topOverflowBeforeHidden = selectedRect.top - popperRect.top;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setOverflow() {
|
||||||
|
if (this.bottomOverflowBeforeHidden > 0) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.dropdownUl.scrollTop += this.bottomOverflowBeforeHidden;
|
||||||
|
});
|
||||||
|
} else if (this.topOverflowBeforeHidden < 0) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.dropdownUl.scrollTop += this.topOverflowBeforeHidden;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelected() {
|
||||||
|
if (!this.multiple) {
|
||||||
|
let option = this.options.filter(option => option.value === this.value)[0] ||
|
||||||
|
{ value: this.value, currentLabel: this.value };
|
||||||
|
this.selectedLabel = option.currentLabel;
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
let result = [];
|
||||||
|
if (Array.isArray(this.value)) {
|
||||||
|
this.value.forEach(value => {
|
||||||
|
let option = this.options.filter(option => option.value === value)[0];
|
||||||
|
if (option) {
|
||||||
|
result.push(option);
|
||||||
|
} else {
|
||||||
|
result.push({
|
||||||
|
value: this.value,
|
||||||
|
currentLabel: value,
|
||||||
|
hitState: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleIconClick(event) {
|
||||||
|
if (this.iconClass === 'circle-close') {
|
||||||
|
this.deleteSelected(event);
|
||||||
|
} else {
|
||||||
|
this.toggleMenu();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleMouseDown(event) {
|
handleMouseDown(event) {
|
||||||
if (event.target.tagName !== 'INPUT') return;
|
if (event.target.tagName !== 'INPUT') return;
|
||||||
if (this.visible) {
|
if (this.visible) {
|
||||||
|
@ -363,22 +395,7 @@
|
||||||
|
|
||||||
deletePrevTag(e) {
|
deletePrevTag(e) {
|
||||||
if (e.target.value.length <= 0 && !this.toggleLastOptionHitState()) {
|
if (e.target.value.length <= 0 && !this.toggleLastOptionHitState()) {
|
||||||
this.selected.pop();
|
this.value.pop();
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addOptionToValue(option, init) {
|
|
||||||
if (this.multiple) {
|
|
||||||
if (this.selected.indexOf(option) === -1 && (this.remote ? this.value.indexOf(option.value) === -1 : true)) {
|
|
||||||
this.selectedInit = !!init;
|
|
||||||
this.selected.push(option);
|
|
||||||
this.resetHoverIndex();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.selectedInit = !!init;
|
|
||||||
this.selected = option;
|
|
||||||
this.selectedLabel = option.currentLabel;
|
|
||||||
this.hoverIndex = option.index;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -418,20 +435,24 @@
|
||||||
|
|
||||||
handleOptionSelect(option) {
|
handleOptionSelect(option) {
|
||||||
if (!this.multiple) {
|
if (!this.multiple) {
|
||||||
this.selected = option;
|
this.$emit('input', option.value);
|
||||||
this.selectedLabel = option.currentLabel;
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
} else {
|
} else {
|
||||||
let optionIndex = -1;
|
let optionIndex = -1;
|
||||||
this.selected.forEach((item, index) => {
|
this.value.forEach((item, index) => {
|
||||||
if (item === option || item.currentValue === option.currentValue) {
|
if (item === option.value) {
|
||||||
optionIndex = index;
|
optionIndex = index;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (optionIndex > -1) {
|
if (optionIndex > -1) {
|
||||||
this.selected.splice(optionIndex, 1);
|
this.value.splice(optionIndex, 1);
|
||||||
} else {
|
} else if (this.multipleLimit <= 0 || this.value.length < this.multipleLimit) {
|
||||||
this.selected.push(option);
|
this.value.push(option.value);
|
||||||
|
}
|
||||||
|
if (option.created) {
|
||||||
|
this.query = '';
|
||||||
|
this.inputLength = 20;
|
||||||
|
this.$refs.input.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -450,6 +471,7 @@
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this.options.length === 0 || this.filteredOptionsCount === 0) return;
|
||||||
if (!this.optionsAllDisabled) {
|
if (!this.optionsAllDisabled) {
|
||||||
if (direction === 'next') {
|
if (direction === 'next') {
|
||||||
this.hoverIndex++;
|
this.hoverIndex++;
|
||||||
|
@ -479,8 +501,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
resetScrollTop() {
|
resetScrollTop() {
|
||||||
let bottomOverflowDistance = this.options[this.hoverIndex].$el.getBoundingClientRect().bottom - this.$refs.popper.$el.getBoundingClientRect().bottom;
|
let bottomOverflowDistance = this.options[this.hoverIndex].$el.getBoundingClientRect().bottom -
|
||||||
let topOverflowDistance = this.options[this.hoverIndex].$el.getBoundingClientRect().top - this.$refs.popper.$el.getBoundingClientRect().top;
|
this.$refs.popper.$el.getBoundingClientRect().bottom;
|
||||||
|
let topOverflowDistance = this.options[this.hoverIndex].$el.getBoundingClientRect().top -
|
||||||
|
this.$refs.popper.$el.getBoundingClientRect().top;
|
||||||
if (bottomOverflowDistance > 0) {
|
if (bottomOverflowDistance > 0) {
|
||||||
this.dropdownUl.scrollTop += bottomOverflowDistance;
|
this.dropdownUl.scrollTop += bottomOverflowDistance;
|
||||||
}
|
}
|
||||||
|
@ -497,8 +521,6 @@
|
||||||
|
|
||||||
deleteSelected(event) {
|
deleteSelected(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.selected = {};
|
|
||||||
this.selectedLabel = '';
|
|
||||||
this.$emit('input', '');
|
this.$emit('input', '');
|
||||||
this.$emit('change', '');
|
this.$emit('change', '');
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
@ -507,13 +529,13 @@
|
||||||
deleteTag(event, tag) {
|
deleteTag(event, tag) {
|
||||||
let index = this.selected.indexOf(tag);
|
let index = this.selected.indexOf(tag);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.selected.splice(index, 1);
|
this.value.splice(index, 1);
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
onInputChange() {
|
onInputChange() {
|
||||||
if (this.filterable && this.selectedLabel !== this.value) {
|
if (this.filterable) {
|
||||||
this.query = this.selectedLabel;
|
this.query = this.selectedLabel;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -535,9 +557,11 @@
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.cachedPlaceHolder = this.currentPlaceholder = this.placeholder;
|
this.cachedPlaceHolder = this.currentPlaceholder = this.placeholder;
|
||||||
if (this.multiple) {
|
if (this.multiple && !Array.isArray(this.value)) {
|
||||||
this.selectedInit = true;
|
this.$emit('input', []);
|
||||||
this.selected = [];
|
}
|
||||||
|
if (!this.multiple && (!this.value || Array.isArray(this.value))) {
|
||||||
|
this.$emit('input', '');
|
||||||
}
|
}
|
||||||
if (this.remote) {
|
if (this.remote) {
|
||||||
this.voidRemoteQuery = true;
|
this.voidRemoteQuery = true;
|
||||||
|
@ -547,20 +571,18 @@
|
||||||
this.onInputChange();
|
this.onInputChange();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$on('addOptionToValue', this.addOptionToValue);
|
|
||||||
this.$on('handleOptionClick', this.handleOptionSelect);
|
this.$on('handleOptionClick', this.handleOptionSelect);
|
||||||
this.$on('onOptionDestroy', this.onOptionDestroy);
|
this.$on('onOptionDestroy', this.onOptionDestroy);
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if (this.multiple && Array.isArray(this.value) && this.value.length > 0) {
|
||||||
|
this.currentPlaceholder = '';
|
||||||
|
}
|
||||||
addResizeListener(this.$el, this.resetInputWidth);
|
addResizeListener(this.$el, this.resetInputWidth);
|
||||||
if (this.remote && this.multiple && Array.isArray(this.value)) {
|
this.selected = this.getSelected();
|
||||||
this.selected = this.options.reduce((prev, curr) => {
|
if (this.remote && this.multiple) {
|
||||||
return this.value.indexOf(curr.value) > -1 ? prev.concat(curr) : prev;
|
|
||||||
}, []);
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.resetInputHeight();
|
this.resetInputHeight();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.reference.$el) {
|
if (this.$refs.reference.$el) {
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
width: 110px;
|
width: 110px;
|
||||||
input {
|
input {
|
||||||
padding-right: 25px;
|
padding-right: 25px;
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
|
height: 28px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,5 +51,9 @@
|
||||||
max-height: var(--select-dropdown-max-height);
|
max-height: var(--select-dropdown-max-height);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
@when empty {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,6 @@
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@when small {
|
|
||||||
& input {
|
|
||||||
border-radius: var(--border-radius-small);
|
|
||||||
height: 28px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
border-color: var(--select-border-color-hover);
|
border-color: var(--select-border-color-hover);
|
||||||
|
|
|
@ -3,9 +3,10 @@ import Select from 'packages/select';
|
||||||
|
|
||||||
describe('Select', () => {
|
describe('Select', () => {
|
||||||
const getSelectVm = (configs = {}, options) => {
|
const getSelectVm = (configs = {}, options) => {
|
||||||
['multiple', 'clearable', 'filterable', 'remote'].forEach(config => {
|
['multiple', 'clearable', 'filterable', 'allowCreate', 'remote'].forEach(config => {
|
||||||
configs[config] = configs[config] || false;
|
configs[config] = configs[config] || false;
|
||||||
});
|
});
|
||||||
|
configs.multipleLimit = configs.multipleLimit || 0;
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = [{
|
options = [{
|
||||||
value: '选项1',
|
value: '选项1',
|
||||||
|
@ -35,8 +36,10 @@ describe('Select', () => {
|
||||||
<el-select
|
<el-select
|
||||||
v-model="value"
|
v-model="value"
|
||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
|
:multiple-limit="multipleLimit"
|
||||||
:clearable="clearable"
|
:clearable="clearable"
|
||||||
:filterable="filterable"
|
:filterable="filterable"
|
||||||
|
:allow-create="allowCreate"
|
||||||
:filterMethod="filterMethod"
|
:filterMethod="filterMethod"
|
||||||
:remote="remote"
|
:remote="remote"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
@ -55,8 +58,10 @@ describe('Select', () => {
|
||||||
return {
|
return {
|
||||||
options,
|
options,
|
||||||
multiple: configs.multiple,
|
multiple: configs.multiple,
|
||||||
|
multipleLimit: configs.multipleLimit,
|
||||||
clearable: configs.clearable,
|
clearable: configs.clearable,
|
||||||
filterable: configs.filterable,
|
filterable: configs.filterable,
|
||||||
|
allowCreate: configs.allowCreate,
|
||||||
loading: false,
|
loading: false,
|
||||||
filterMethod: configs.filterMethod && configs.filterMethod(this),
|
filterMethod: configs.filterMethod && configs.filterMethod(this),
|
||||||
remote: configs.remote,
|
remote: configs.remote,
|
||||||
|
@ -349,6 +354,23 @@ describe('Select', () => {
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allow create', done => {
|
||||||
|
vm = getSelectVm({ filterable: true, allowCreate: true });
|
||||||
|
const select = vm.$children[0];
|
||||||
|
select.selectedLabel = 'new';
|
||||||
|
select.onInputChange();
|
||||||
|
select.visible = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
const options = document.querySelectorAll('.el-select-dropdown__item span');
|
||||||
|
const target = [].filter.call(options, option => option.innerText === 'new');
|
||||||
|
target[0].click();
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(select.value.indexOf('new') > -1).to.true;
|
||||||
|
done();
|
||||||
|
}, 50);
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
|
||||||
it('multiple select', done => {
|
it('multiple select', done => {
|
||||||
vm = getSelectVm({ multiple: true });
|
vm = getSelectVm({ multiple: true });
|
||||||
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
|
const options = vm.$el.querySelectorAll('.el-select-dropdown__item');
|
||||||
|
@ -368,6 +390,20 @@ describe('Select', () => {
|
||||||
}, 100);
|
}, 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 => {
|
it('multiple remote search', done => {
|
||||||
const remoteMethod = vm => {
|
const remoteMethod = vm => {
|
||||||
return query => {
|
return query => {
|
||||||
|
@ -387,6 +423,7 @@ describe('Select', () => {
|
||||||
remoteMethod
|
remoteMethod
|
||||||
});
|
});
|
||||||
const select = vm.$children[0];
|
const select = vm.$children[0];
|
||||||
|
vm.$nextTick(() => {
|
||||||
select.query = '面';
|
select.query = '面';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(select.filteredOptionsCount).to.equal(1);
|
expect(select.filteredOptionsCount).to.equal(1);
|
||||||
|
@ -405,3 +442,4 @@ describe('Select', () => {
|
||||||
}, 250);
|
}, 250);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue