修改el-autocomplete下拉列表的样式
继上一篇文章,需求需要修改下拉列表的宽度后。
又来新活了,这次需要在下拉列表底部增加一个快捷新增按钮,如图所示。
看了一遍文档,el-autocomplete并没有提供这样的底部插槽。只有一个item的插槽,可以自定义模板。
但这只能控制每一项的内容,并不能在底部添加一个自定义内容,除非通过操作dom的方式去动态添加。
在准备放弃使用el-autocomplete,改用el-select来实现需求的时候。我在element-ui的官网发现了他的搜索框,使用el-autocomplete做到了这一点。
因为不知道他源码是怎么实现的,就分析了一下他的dom结构。可以看到他底部也是与其他数据一样,用li包裹的。
只是最后一项,只有一个a标签,还有几行注释代码。看到这里就能大概猜出实现方式了。
1.使用组件提供的item插槽自定义模板
2.给搜索出来的数据添加一条假数据,作为固定行的占位
3.在插槽里通过v-if的方式去控制显示。
4.最主要的一点就是,如何固定这一行在底部,不随滚动条一起滚动。这里就需要作用样式,刚好组件有提供一个poper-class 的 Attribute。
下面上代码。
<template v-slot:acc_no_edit="{ row }">
<el-autocomplete
class="inline-input"
ref="accNoSearch"
v-model="row.acc_name"
:popper-append-to-body="false"
:fetch-suggestions="querySearch"
popper-class="acc-search"
size="medium"
@select="handleSelect($event,row)"
clearable
@clear="clearSelect(row)"
@keydown.enter.native="handleSelect(null,row)"
value-key="acc_title"
>
<template slot-scope="{ item }">
<el-button
v-if="item.is_add"
v-permission="['comp_sys_add_account']"
type="text"
class="add-button"
@click="accAddBtn()"
>
{{ $t('voucher.table.body.add_subject') }}
</el-button>
<div class="content" v-else>
{{ item.acc_title }}
</div>
</template>
</el-autocomplete>
</template>
// 搜索框带输入建议
querySearch(queryString, cb) {
let results = []
results = queryString
? this.accList.filter(this.createFilter(queryString))
: this.accList
// 添加假数据作为固定新增行
results.push({ id: -1, is_add: true, acc_title: '' })
// 调用 callback 返回建议列表的数据
this.query_result = results
cb(results)
},
createFilter(queryString) {
return (item) => {
return item.acc_title.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
}
},
<style lang="scss" scoped>
::v-deep.el-autocomplete .el-popper{
min-width: 327px;
width: auto !important;
}
// 防止最后一条数据被固定行盖住
::v-deep.el-autocomplete .el-autocomplete-suggestion__wrap{
margin-bottom: 15px !important;
}
// 将快捷新增按钮固定在底部
::v-deep.el-autocomplete .acc-search .add-button{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding-right: 20px;
background-color: #e4e7ed;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
box-sizing: border-box;
text-align: center;
}
</style>
最终效果: