1、问题描述
elementui2.x版本使用el-select组件的remote-method远程查找时,发现下拉箭头丢失了,且当查找接口返回数据为空时,也不会展开下拉列表来显示暂无数据提示;
2、源码解析
官网使用示例:
<template><el-selectv-model="value"multiplefilterableremotereserve-keywordplaceholder="请输入关键词":remote-method="remoteMethod":loading="loading"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"></el-option></el-select>
</template>
ElSelect组件源码问题解析:
1、查看源码发现是当props属性remote 和filterable 都为true时,导致计算属性iconClass返回的是空字符,所以下拉箭头不显示;
computed:{...前面代码省略iconClass() {return this.remote && this.filterable ? '' : (this.visible ? 'arrow-up is-reverse' : 'arrow-up');},...后面代码省略
}
2、分析下面代码,发现下拉框只有在emptyText不为false且visible为true的情况下才会显示,且empty部分也必须emptyText有值才会显示,所以得去找emptyText;
<!-- 前面代码省略 -->
<transitionname="el-zoom-in-top"@before-enter="handleMenuEnter"@after-leave="doDestroy"><el-select-menuref="popper":append-to-body="popperAppendToBody"v-show="visible && emptyText !== false"><el-scrollbartag="ul"wrap-class="el-select-dropdown__wrap"view-class="el-select-dropdown__list"ref="scrollbar":class="{ 'is-empty': !allowCreate && query && filteredOptionsCount === 0 }"v-show="options.length > 0 && !loading"><el-option:value="query"createdv-if="showNewOption"></el-option><slot></slot></el-scrollbar><template v-if="emptyText && (!allowCreate || loading || (allowCreate && options.length === 0 ))"><slot name="empty" v-if="$slots.empty"></slot><p class="el-select-dropdown__empty" v-else>{{ emptyText }}</p></template></el-select-menu></transition></div>
</template>
3、找到emptyText代码分析发现,当remote为true,且query为空,options数组长度为0时,返回的是false,也就导致为什么当远程查询无数据时下拉框不显示的问题;
computed:{...前面代码省略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.query && 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;},...后面代码省略
}
3、解决办法(不想看源码解析可直接跳转到这里)
创建一个js文件(例如select.js),目录位置自己定,里面内容如下:
export default {computed: {iconClass() {return this.visible ? 'arrow-up is-reverse' : 'arrow-up';},emptyText() {if (this.loading) {return this.loadingText || this.t('el.select.loading');} else {if (this.remote && this.query === '' && this.options.length === 0) {return this.noMatchText || this.t('el.select.noMatch');};if (this.filterable && this.query && 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;},}
}
在main.js中导入并使用对象结构合并到ElementUI.Select.computed上,注意这里必须要用结构来覆盖原有值,使用mixins混入是无效的(亲测),且结构最好在Vue.use(ElementUI, { size: 'mini' })前进行;
import Vue from 'vue'
import ElementUI from 'element-ui';
import '@/style/element-variables.scss'import select_mixin from '@/components/elementui/mixins/select';
ElementUI.Select.computed = {...ElementUI.Select.computed, ...select_mixin.computed};
Vue.use(ElementUI, { size: 'mini' });