我使用的element-ui的版本是1.4.13。
如上图所示,使用el-select组件,要实现可搜索、可复选、可创建条目时,展示样式是如上图所示,输入框的高度会撑开,影响页面布局,按照产品的需求,要调整为以下样式:
1、复选时,输入框中不以标签的形式展示,而是以字符串的形式展示。
2、超出部分显示省略号,并且鼠标移入显示提示框,用来展示全选的内容。
下面是源码修改部分:
(1)在select的props中添加了一个参数noTag用来控制是否以字符串形式显示输入框中的数据。添加了上面的el-popover标签,主要是文字超出时显示,这个后面再讲。底下的span标签就是在noTag参数为true时显示,data中添加currentSelLabel,用来显示处理后的多选数据,将数组转成字符串。
(2)在这里加了一个类,主要是方便后面加span标签的css样式。在select.css文件中的css样式如下面代码所示:
.el-select__tags.noTags .noTagSpan{
display: inline-block;
font-size: 12px;
width: 100%;
padding:0 6px;
overflow: hidden; /*自动隐藏文字*/
text-overflow: ellipsis; /*文字隐藏后添加省略号*/
white-space: nowrap; /*强制不换行*/
}
(3)在noTag参数为true时显示class="noTagSpan"的span标签时,对应的el-tag标签就不再显示,如图所示,也需要在el-tag标签中添加noTag控制
(4)在setSelected方法中处理多选时的数据,将数组转成字符串,如下图所示:
(5)文字超出时显示提示框,效果如下:
需要在methods中添加如下方法:
//当复选时文字超出输入框,出现提示框
showSpanTooltip: function (event) {
if(!this.showpop) return;
var ev = event || window.event;
var eventName = ev.target.className;
if (eventName.indexOf('noTagSpan') != -1) {
if (ev.target.offsetWidth < ev.target.scrollWidth) {
var tooltip = this.$refs.textTooltip;
tooltip.referenceElm = ev.target;
tooltip.$refs.popper.style.display = 'none';
tooltip.doDestroy();
tooltip.showPopper = true;
}
}
},
//当复选时文字超出输入框,隐藏提示框
hiddenSpanTooltip: function () {
if(!this.showpop) return;
const tooltip = this.$refs.textTooltip;
if (tooltip) {
tooltip.doClose() ;
tooltip.doDestroy();
}
}
(6)多选时,可搜索。按照组件现在的,搜索框会在选项的下面出现,这样会撑开输入框的高度。
这里需要调整,将输入框放在下面的下拉菜单中,如图所示:
代码如下:
避免跟element原有的搜索框冲突,加了参数控制:
需要在select.css加入如下样式:
.noTagInputDiv{
border: 1px solid rgb(191, 193, 217);
margin-left: -1px;
margin-top:-30px;
width: 100%;
max-width: 185px;
padding-right: 30px;
overflow: hidden; /*自动隐藏文字*/
text-overflow: ellipsis; /*文字隐藏后添加省略号*/
white-space: nowrap; /*强制不换行*/
}
这个时候需要在下拉出现的时候调整整个下拉菜单的位置,具体修改代码的地方如下:
在data中加入initPopperTop,用来记录初始时下拉菜单的位置:
1、在watch中的visible中
2、在watch中的query中
3、methods的resetInputHeight方法中
(7)多选时并且可搜索时,如果条目不存在时,创建条目,并且显示在下拉菜单中,这样可以通过反选删除选中的数据。
1、添加el-option标签,用来显示创建的条目。在data中添加mulOptions数组,用来记录创建的条目。
2、handleOptionSelect方法中处理数据
3、在option.vue的props中添加optcreated
ok,所有的就改完了,效果如图所示:
以下附源码:
<template>
<div
class="el-select"
v-clickoutside="handleClose">
<div
class="el-select__tags"
:class="{'noTags':noTag}"
v-if="multiple"
@click.stop="toggleMenu"
ref="tags"
:style="{ 'max-width': inputWidth - 32 + 'px' }">
<transition-group @after-leave="resetInputHeight">
<el-tag
v-if="!noTag"
v-for="item in selected"
:key="getValueKey(item)"
closable
:hit="item.hitState"
type="primary"
@close="deleteTag($event, item)"
close-transition>
<span class="el-select__tags-text">{{ item.currentLabel }}</span>
</el-tag>
</transition-group>
<el-popover
ref="textTooltip"
placement="top-start"
width="200"
trigger="hover"
:content="currentSelLabel">
</el-popover>
<span v-if="noTag" class="noTagSpan"
@mouseenter="showSpanTooltip($event)" @mouseleave="hiddenSpanTooltip($event)">
{{currentSelLabel}}
</span>
<input
type="text"
class="el-select__input"
:class="`is-${ size }`"
@focus="visible = true"
:disabled="disabled"
@keyup="managePlaceholder"
@keydown="resetInputState"
@keydown.down.prevent="navigateOptions('next')"
@keydown.up.prevent="navigateOptions('prev')"
@keydown.enter.prevent="selectOption"
@keydown.esc.stop.prevent="visible = false"
@keydown.delete="deletePrevTag"
v-model="query"
:debounce="remote ? 300 : 0"
v-if="filterable && !noTag"
:style="{ width: inputLength + 'px', 'max-width': inputWidth - 42 + 'px' }"
ref="input">
</div>
<el-input
ref="reference"
v-model="selectedLabel"
type="text"
:placeholder="currentPlaceholder"
:name="name"
:size="size"
:disabled="disabled"
:readonly="!filterable || multiple"
:validate-event="false"
@focus="handleFocus"
@click="handleIconClick"
@mousedown.native="handleMouseDown"
@keyup.native="debouncedOnInputChange"
@keydown.native.down.prevent="navigateOptions('next')"
@keydown.native.up.prevent="navigateOptions('prev')"
@keydown.native.enter.prevent="selectOption"
@keydown.native.esc.stop.prevent="visible = false"
@keydown.native.tab="visible = false"
@paste.native="debouncedOnInputChange"
@mouseenter.native="inputHovering = true"
@mouseleave.native="inputHovering = false"
:icon="iconClass">
</el-input>
<transition
name="el-zoom-in-top"
@before-enter="handleMenuEnter"
@after-leave="doDestroy">
<el-select-menu
ref="popper"
v-show="visible && emptyText !== false">
<!--有noTag时搜索框在下面显示-->
<div v-if="filterable && noTag && multiple" :class="{'noTagInputDiv':noTag}">
<input
type="text"
class="el-select__input"
:class="`is-${ size }`"
@focus="visible = true"
:disabled="disabled"
@keyup="managePlaceholder"
@keydown="resetInputState"
@keydown.down.prevent="navigateOptions('next')"
@keydown.up.prevent="navigateOptions('prev')"
@keydown.enter.prevent="selectOption"
@keydown.esc.stop.prevent="visible = false"
@keydown.delete="deletePrevTag"
v-model="query"
:debounce="remote ? 300 : 0"
v-if="filterable && noTag && multiple"
:style="{ width: inputLength + 'px', 'max-width': inputWidth - 42 + 'px' }"
ref="input">
</div>
<el-input v-model="search" @focus="visible = true" v-if="searchable"></el-input>
<el-scrollbar
tag="ul"
wrap-class="el-select-dropdown__wrap"
view-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>
<el-option
v-if="noTag && multiple && allowCreate"
v-for="item in mulOptions"
:key="item.currentLabel"
:optcreated="item.optcreated"
:value="item.currentLabel">
</el-option>
<slot></slot>
</el-scrollbar>
<p class="el-select-dropdown__empty" v-if="emptyText && (allowCreate && options.length === 0 || !allowCreate)">{{ emptyText }}</p>
</el-select-menu>
</transition>
</div>
</template>
<script type="text/babel">
import Emitter from 'element-ui/src/mixins/emitter';
import Locale from 'element-ui/src/mixins/locale';
import ElInput from 'element-ui/packages/input';
import ElSelectMenu from './select-dropdown.vue';
import ElOption from './option.vue';
import ElTag from 'element-ui/packages/tag';
import ElScrollbar from 'element-ui/packages/scrollbar';
import debounce from 'throttle-debounce/debounce';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import { addClass, removeClass, hasClass } from 'element-ui/src/utils/dom';
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
import { t } from 'element-ui/src/locale';
import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
import { getValueByPath } from 'element-ui/src/utils/util';
const sizeMap = {
'large': 42,
'small': 30,
'mini': 22
};
export default {
mixins: [Emitter, Locale],
name: 'ElSelect',
componentName: 'ElSelect',
computed: {
iconClass() {
let criteria = this.clearable &&
!this.disabled &&
this.inputHovering &&
!this.multiple &&
this.value !== undefined &&
this.value !== '';
return criteria ? 'circle-close is-show-close' : (this.remote && this.filterable ? '' : 'caret-top');
},
debounce() {
return this.remote ? 300 : 0;
},
emptyText() {
if (this.loading) {
return this.loadingText || this.t('el.select.loading');
} else {
if (this.remote && this.query === '' && this.options.length === 0) return false;
if (this.filterable && this.options.length > 0 && this.filteredOptionsCount === 0) {
return this.noMatchText || this.t('el.select.noMatch');
}
if (this.options.length === 0) {
return this.noDataText || this.t('el.select.noData');
}
}
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: {
ElInput,
ElSelectMenu,
ElOption,
ElTag,
ElScrollbar
},
directives: { Clickoutside },
props: {
name: String,
value: {
required: true
},
size: String,
disabled: Boolean,
clearable: Boolean,
filterable: Boolean,
searchable: Boolean,
allowCreate: Boolean,
noTag:Boolean, //多选的时候是否以字符串形式展示 f
showpop: { //是否在文字超出span标签的时候显示提示 f
type: Boolean,
default: true
},
loading: Boolean,
popperClass: String,
remote: Boolean,
loadingText: String,
noMatchText: String,
noDataText: String,
remoteMethod: Function,
filterMethod: Function,
multiple: Boolean,
multipleLimit: {
type: Number,
default: 0
},
placeholder: {
type: String,
default() {
return t('el.select.placeholder');
}
},
defaultFirstOption: Boolean,
valueKey: {
type: String,
default: 'value'
}
},
data() {
return {
options: [],
cachedOptions: [],
createdLabel: null,
createdSelected: false,
selected: this.multiple ? [] : {},
isSelect: true,
inputLength: 20,
inputWidth: 0,
cachedPlaceHolder: '',
optionsCount: 0,
filteredOptionsCount: 0,
visible: false,
selectedLabel: '',
hoverIndex: -1,
query: '',
search: '',
optionsAllDisabled: false,
inputHovering: false,
currentPlaceholder: '',
currentSelLabel:'', //多选时以字符串形式展示的标签 f
initPopperTop:0, //初始时下拉框的位置 f
mulOptions:[] //多选时添加的数据 f
};
},
watch: {
placeholder(val) {
this.cachedPlaceHolder = this.currentPlaceholder = val;
},
value(val) {
if (this.multiple) {
this.resetInputHeight();
if (val.length > 0 || (this.$refs.input && this.query !== '')) {
this.currentPlaceholder = '';
} else {
this.currentPlaceholder = this.cachedPlaceHolder;
}
}
this.setSelected();
if (this.filterable && !this.multiple) {
this.inputLength = 20;
}
this.$emit('change', val);
this.dispatch('ElFormItem', 'el.form.change', val);
},
search(val) {
if (this.searchable) {
this.$emit('search-change', val);
}
},
query(val) {
this.$nextTick(() => {
if (this.visible) {
this.broadcast('ElSelectDropdown', 'updatePopper');
//multiple、noTag、filterable 同时存在时,调整下拉框位置
if(this.multiple && this.noTag && this.filterable){
this.$nextTick(()=>{
var popperTop = window.getComputedStyle? window.getComputedStyle(this.$refs.popper.$el).top : this.$refs.popper.$el.currentStyle.top;
this.$refs.popper.$el.style.top = parseInt(popperTop)+ 25+'px';
})
}
}
});
this.hoverIndex = -1;
if (this.multiple && this.filterable) {
this.inputLength = this.$refs.input.value.length * 15 + 20;
this.managePlaceholder();
this.resetInputHeight();
}
if (this.remote && typeof this.remoteMethod === 'function') {
this.hoverIndex = -1;
this.remoteMethod(val);
this.broadcast('ElOption', 'resetIndex');
} else if (typeof this.filterMethod === 'function') {
this.filterMethod(val);
this.broadcast('ElOptionGroup', 'queryChange');
} else {
this.filteredOptionsCount = this.optionsCount;
this.broadcast('ElOption', 'queryChange', val);
this.broadcast('ElOptionGroup', 'queryChange');
}
if (this.defaultFirstOption && (this.filterable || this.remote) && this.filteredOptionsCount) {
this.checkDefaultFirstOption();
}
},
visible(val) {
if (!val) {
this.$refs.reference.$el.querySelector('input').blur();
this.handleIconHide();
this.broadcast('ElSelectDropdown', 'destroyPopper');
if (this.$refs.input) {
this.$refs.input.blur();
}
this.query = '';
this.selectedLabel = '';
this.inputLength = 20;
this.resetHoverIndex();
this.$nextTick(() => {
if (this.$refs.input &&
this.$refs.input.value === '' &&
this.selected.length === 0) {
this.currentPlaceholder = this.cachedPlaceHolder;
}
});
if (!this.multiple) {
if (this.selected) {
if (this.filterable && this.allowCreate &&
this.createdSelected && this.createdLabel) {
this.selectedLabel = this.createdLabel;
} else {
this.selectedLabel = this.selected.currentLabel;
}
if (this.filterable) this.query = this.selectedLabel;
}
}
} else {
this.handleIconShow();
this.broadcast('ElSelectDropdown', 'updatePopper');
//multiple、noTag、filterable 同时存在时,调整下拉框位置,并记录初始下拉框的位置
if(this.multiple && this.noTag && this.filterable){
this.$nextTick(()=>{
this.$refs.input.focus();
var popperTop = window.getComputedStyle? window.getComputedStyle(this.$refs.popper.$el).top : this.$refs.popper.$el.currentStyle.top;
//记录初始下拉框的位置
this.initPopperTop = popperTop;
this.$refs.popper.$el.style.top = parseInt(popperTop) + 25 +'px';
})
}
if (this.filterable) {
this.query = this.selectedLabel;
if (this.multiple) {
this.$refs.input.focus();
} else {
if (!this.remote) {
this.broadcast('ElOption', 'queryChange', '');
this.broadcast('ElOptionGroup', 'queryChange');
}
this.broadcast('ElInput', 'inputSelect');
}
}
}
this.$emit('visible-change', val);
},
options(val) {
if (this.$isServer) return;
this.optionsAllDisabled = val.length === val.filter(item => item.disabled === true).length;
if (this.multiple) {
this.resetInputHeight();
}
let inputs = this.$el.querySelectorAll('input');
if ([].indexOf.call(inputs, document.activeElement) === -1) {
this.setSelected();
}
if (this.defaultFirstOption && (this.filterable || this.remote) && this.filteredOptionsCount) {
this.checkDefaultFirstOption();
}
}
},
methods: {
//当复选时文字超出输入框,出现提示框
showSpanTooltip: function (event) {
if(!this.showpop) return;
var ev = event || window.event;
var eventName = ev.target.className;
if (eventName.indexOf('noTagSpan') != -1) {
if (ev.target.offsetWidth < ev.target.scrollWidth) {
var tooltip = this.$refs.textTooltip;
tooltip.referenceElm = ev.target;
tooltip.$refs.popper.style.display = 'none';
tooltip.doDestroy();
tooltip.showPopper = true;
}
}
},
//当复选时文字超出输入框,隐藏提示框
hiddenSpanTooltip: function () {
if(!this.showpop) return;
const tooltip = this.$refs.textTooltip;
if (tooltip) {
tooltip.doClose() ;
tooltip.doDestroy();
}
},
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');
}
},
scrollToOption(className = 'selected') {
const menu = this.$refs.popper.$el.querySelector('.el-select-dropdown__wrap');
scrollIntoView(menu, menu.getElementsByClassName(className)[0]);
},
handleMenuEnter() {
this.$nextTick(() => this.scrollToOption());
},
getOption(value) {
let option;
const type = typeof value;
const isObject = type !== 'string' && type !== 'number' && type !== 'boolean';
for (let i = this.cachedOptions.length - 1; i >= 0; i--) {
const cachedOption = this.cachedOptions[i];
const isEqual = isObject
? this.getValueByPath(cachedOption.value, this.valueKey) === this.getValueByPath(value, this.valueKey)
: cachedOption.value === value;
if (isEqual) {
option = cachedOption;
break;
}
}
if (option) return option;
const label = !isObject
? value : '';
let newOption = {
value: value,
currentLabel: label
};
if (this.multiple) {
newOption.hitState = false;
}
return newOption;
},
getValueByPath(object, prop) {
prop = prop || '';
const paths = prop.split('.');
let current = object;
let result = null;
for (let i = 0, j = paths.length; i < j; i++) {
const path = paths[i];
if (current !== 0 && !current) break;
if (i === j - 1) {
result = current[path];
break;
}
current = current[path];
}
return result;
},
setSelected() {
if (!this.multiple) {
let option = this.getOption(this.value);
if (option.created) {
this.createdLabel = option.currentLabel;
this.createdSelected = true;
} else {
this.createdSelected = false;
}
this.selectedLabel = option.currentLabel;
this.selected = option;
if (this.filterable) this.query = this.selectedLabel;
return;
}
let result = [];
if (Array.isArray(this.value)) {
this.value.forEach(value => {
result.push(this.getOption(value));
});
}
this.selected = result;
//复选时,选项以字符串的形式显示,此处处理显示数据,数组转成字符串
if(this.noTag && this.multiple){
var arr = [];
if(this.selected && this.selected.length){
this.selected.forEach(function(item){
arr.push(item.currentLabel);
})
}
this.currentSelLabel = arr.join(',');
}
this.$nextTick(() => {
this.resetInputHeight();
});
},
handleFocus() {
this.visible = true;
},
handleIconClick(event) {
if (this.iconClass.indexOf('circle-close') > -1) {
this.deleteSelected(event);
} else {
this.toggleMenu();
}
},
handleMouseDown(event) {
if (event.target.tagName !== 'INPUT') return;
if (this.visible) {
this.handleClose();
event.preventDefault();
}
},
doDestroy() {
this.$refs.popper && this.$refs.popper.doDestroy();
this.dropdownUl = null;
},
handleClose() {
this.visible = false;
},
toggleLastOptionHitState(hit) {
if (!Array.isArray(this.selected)) return;
const option = this.selected[this.selected.length - 1];
if (!option) return;
if (hit === true || hit === false) {
option.hitState = hit;
return hit;
}
option.hitState = !option.hitState;
return option.hitState;
},
deletePrevTag(e) {
if (e.target.value.length <= 0 && !this.toggleLastOptionHitState()) {
const value = this.value.slice();
value.pop();
this.$emit('input', value);
}
},
managePlaceholder() {
if (this.currentPlaceholder !== '') {
this.currentPlaceholder = this.$refs.input.value ? '' : this.cachedPlaceHolder;
}
},
resetInputState(e) {
if (e.keyCode !== 8) this.toggleLastOptionHitState(false);
this.inputLength = this.$refs.input.value.length * 15 + 20;
this.resetInputHeight();
},
resetInputHeight() {
this.$nextTick(() => {
if (!this.$refs.reference) return;
let inputChildNodes = this.$refs.reference.$el.childNodes;
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
input.style.height = Math.max(this.$refs.tags.clientHeight + 6, sizeMap[this.size] || 36) + 'px';
if (this.visible && this.emptyText !== false) {
this.broadcast('ElSelectDropdown', 'updatePopper');
//multiple、noTag、filterable 同时存在时,判断当前下拉框是否在初始位置,不在则调整下拉框位置
if(this.multiple && this.noTag && this.filterable){
this.$nextTick(()=>{
var popperTop = window.getComputedStyle? window.getComputedStyle(this.$refs.popper.$el).top : this.$refs.popper.$el.currentStyle.top;
if(popperTop <= this.initPopperTop){
this.$refs.popper.$el.style.top = parseInt(popperTop)+ 25+'px';
}
})
}
}
});
},
resetHoverIndex() {
setTimeout(() => {
if (!this.multiple) {
this.hoverIndex = this.options.indexOf(this.selected);
} else {
if (this.selected.length > 0) {
this.hoverIndex = Math.min.apply(null, this.selected.map(item => this.options.indexOf(item)));
} else {
this.hoverIndex = -1;
}
}
}, 300);
},
handleOptionSelect(option) {
if (this.multiple) {
const value = this.value.slice();
const optionIndex = this.getValueIndex(value, option.value);
if (optionIndex > -1) {
//multiple、allowCreate存在,复选时可以向下拉列表中删除数据
if(this.allowCreate && option.optcreated && this.noTag){
if(this.mulOptions && this.mulOptions.length){
this.mulOptions.forEach((item,index)=>{
if(item.currentValue == option.currentValue){
this.mulOptions.splice(index, 1);
}
})
}
}
value.splice(optionIndex, 1);
} else if (this.multipleLimit <= 0 || value.length < this.multipleLimit) {
value.push(option.value);
}
this.$emit('input', value);
if (option.created) {
//multiple、allowCreate存在,复选时可以像下拉列表中添加数据
if(this.allowCreate && this.noTag && !option.optcreated){
var obj = {
optcreated:true,
created:option.created,
currentLabel:option.currentLabel,
currentValue:option.currentValue
}
this.mulOptions.push(obj);
}
this.query = '';
this.inputLength = 20;
}
if (this.filterable) this.$refs.input.focus();
} else {
this.$emit('input', option.value);
this.visible = false;
}
this.$nextTick(() => this.scrollToOption());
},
getValueIndex(arr = [], value) {
const type = typeof value;
const isObject = type !== 'string' && type !== 'number' && type !== 'boolean';
if (!isObject) {
return arr.indexOf(value);
} else {
const valueKey = this.valueKey;
let index = -1;
arr.some((item, i) => {
if (getValueByPath(item, valueKey) === getValueByPath(value, valueKey)) {
index = i;
return true;
}
return false;
});
return index;
}
},
toggleMenu() {
if (this.filterable && this.query === '' && this.visible) {
return;
}
if (!this.disabled) {
this.visible = !this.visible;
}
},
navigateOptions(direction) {
if (!this.visible) {
this.visible = true;
return;
}
if (this.options.length === 0 || this.filteredOptionsCount === 0) return;
this.optionsAllDisabled = this.options.length === this.options.filter(item => item.disabled === true).length;
if (!this.optionsAllDisabled) {
if (direction === 'next') {
this.hoverIndex++;
if (this.hoverIndex === this.options.length) {
this.hoverIndex = 0;
}
if (this.options[this.hoverIndex].disabled === true ||
this.options[this.hoverIndex].groupDisabled === true ||
!this.options[this.hoverIndex].visible) {
this.navigateOptions('next');
}
}
if (direction === 'prev') {
this.hoverIndex--;
if (this.hoverIndex < 0) {
this.hoverIndex = this.options.length - 1;
}
if (this.options[this.hoverIndex].disabled === true ||
this.options[this.hoverIndex].groupDisabled === true ||
!this.options[this.hoverIndex].visible) {
this.navigateOptions('prev');
}
}
}
this.$nextTick(() => this.scrollToOption('hover'));
},
selectOption() {
if (this.options[this.hoverIndex]) {
this.handleOptionSelect(this.options[this.hoverIndex]);
}
},
deleteSelected(event) {
event.stopPropagation();
this.$emit('input', '');
this.visible = false;
this.$emit('clear');
},
deleteTag(event, tag) {
let index = this.selected.indexOf(tag);
if (index > -1 && !this.disabled) {
const value = this.value.slice();
value.splice(index, 1);
this.$emit('input', value);
this.$emit('remove-tag', tag);
}
event.stopPropagation();
},
onInputChange() {
if (this.filterable) {
this.query = this.selectedLabel;
}
},
onOptionDestroy(option) {
this.optionsCount--;
this.filteredOptionsCount--;
let index = this.options.indexOf(option);
if (index > -1) {
this.options.splice(index, 1);
}
this.broadcast('ElOption', 'resetIndex');
},
resetInputWidth() {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
},
handleResize() {
this.resetInputWidth();
if (this.multiple) this.resetInputHeight();
},
checkDefaultFirstOption() {
this.hoverIndex = -1;
for (let i = 0; i !== this.options.length; ++i) {
const option = this.options[i];
if (this.query) {
// pick first options that passes the filter
if (!option.disabled && !option.groupDisabled && option.visible) {
this.hoverIndex = i;
break;
}
} else {
// pick currently selected option
if (option.itemSelected) {
this.hoverIndex = i;
break;
}
}
}
},
getValueKey(item) {
const type = typeof item.value;
if (type === 'number' || type === 'string') {
return item.value;
} else {
return getValueByPath(item.value, this.valueKey);
}
}
},
created() {
this.cachedPlaceHolder = this.currentPlaceholder = this.placeholder;
if (this.multiple && !Array.isArray(this.value)) {
this.$emit('input', []);
}
if (!this.multiple && Array.isArray(this.value)) {
this.$emit('input', '');
}
this.setSelected();
this.debouncedOnInputChange = debounce(this.debounce, () => {
this.onInputChange();
});
this.$on('handleOptionClick', this.handleOptionSelect);
this.$on('onOptionDestroy', this.onOptionDestroy);
this.$on('setSelected', this.setSelected);
},
mounted() {
if (this.multiple && Array.isArray(this.value) && this.value.length > 0) {
this.currentPlaceholder = '';
}
addResizeListener(this.$el, this.handleResize);
if (this.remote && this.multiple) {
this.resetInputHeight();
}
this.$nextTick(() => {
if (this.$refs.reference && this.$refs.reference.$el) {
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
}
});
},
beforeDestroy() {
if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
}
};
// dialog_ref
</script>