使用 el-select 实现 文本搜索输入搜索
参考链接:https://www.cnblogs.com/morango/p/15193035.html
https://blog.csdn.net/qq_32963841/article/details/116160314
需求说明
本身直接使用 el-input 输入搜索,用户有个用select 的时候能输入,就想要 这个输入也能加上下拉提示用户输入。
提示的option 当然是根据接口取获取。
实现思路
本来想直接用 el-select 组件的,但是不大符合效果,因为用户要的是输入,而不是 select 选中之后值,输入可以随意输入值,以我想要的值为准,而不是以 select 中option 匹配的值为准。
方法1: 自己利用 input 整
方法2: 修改 el-select
方法1实践
本来感觉用 el-input + el-select 来实现,可是 focus 时显示下拉不好整,单独拖出来下拉框,就涉及到自己新搞一个组件,想想都比较复杂,成本较高。
放弃,如果方法2不行再继续
方法2实践
这个修改的主要矛盾点在于:elselect的输入值不能实时的保存到对应的值里面
最终经过多次测试(主要是避免出现问题),得到以下代码
html
<el-select
:ref="'s_'+searchField.code"
v-model="searchParams.searchFieldLogic[`${"${searchField.code}$"}`]"
clearable
filterable
remote
default-first-option
:remote-method="query => remoteSearchMethod(query, searchField)"
:loading="remoteSearchLoading[searchField.code]"
@change="(val) => remoteSearchChange(val, searchField)"
@visible-change="(val) => handleVisibleChange(val, searchField)"
@keyup.enter.native="remoteSearchEnterUP(searchField)"
>
<el-option
v-for="item in remoteSearchOptions[searchField.code]"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
import { debounce } from 'lodash'
remoteSearchLoading: {},
remoteSearchOptions: {},
remoteSearchValue: {},
// 搜索框下拉:远程搜索函数
remoteSearchMethod(query, searchField) {
const code = searchField.code
this.searchParams.searchFieldLogic[code] = query // 同步用户输入值
this.remoteSearchOptions[code] = [query]
if (query != '' && this.remoteSearchValue[code] != '') {
this.getRemote(code, query)
}
},
// 搜索框下拉:选中值发生变化时触发
remoteSearchChange(val, searchField) {
const code = searchField.code
if (val == '' || this.remoteSearchValue[code] == '') {
this.remoteSearchOptions[code] = []
this.searchParams.searchFieldLogic[code] = ''
} else if (
this.remoteSearchValue[code] != this.searchParams.searchFieldLogic[code]
) {
// 选中某个选项时改变值 -> 保持一致
this.remoteSearchValue[code] = this.searchParams.searchFieldLogic[code]
}
this.search()
},
// 防抖: 300 ms 触发一次
getRemote: debounce(function (searchFieldCode, query) {
this.remoteSearch(searchFieldCode, query)
}, 300),
async remoteSearch(searchFieldCode, query) {
this.remoteSearchLoading[searchFieldCode] = true
// 请求接口
const res = await 接口(参数..., query)
if (res.success) {
let options = res.data || []
if (options.findIndex(item => item == query) == -1) {
options.unshift(query)
}
this.remoteSearchOptions[searchFieldCode] = options
} else {
this.$message({
showClose: true,
message: res.meta.message,
type: 'error',
})
}
this.remoteSearchLoading[searchFieldCode] = false
},
// 搜索框下拉:下拉框出现/隐藏时触发
handleVisibleChange(val, searchField) {
const select = this.$refs['s_' + searchField.code][0]
const selectInput = select && select.$refs.reference.$el
const code = `${searchField.code}$`
if (val) {
select.selectedLabel = this.searchParams.searchFieldLogic[code]
const input = e => {
this.remoteSearchValue[code] = e.target.value // 同步搜索输入值
}
selectInput._InputFunc_ = input
selectInput.addEventListener('input', input)
} else {
selectInput.removeEventListener('input', selectInput._InputFunc_)
}
},
// 搜索框下拉:enter 键 up 事件
remoteSearchEnterUP(searchField) {
this.$refs['s_' + searchField.code][0].visible = false // 隐藏下拉框
const code = searchField.code
// enter 键 up 时,输入值不为用户想要的输入->重新赋值
if (
this.searchParams.searchFieldLogic[code] != this.remoteSearchValue[code]
) {
this.searchParams.searchFieldLogic[code] = this.remoteSearchValue[code]
}
if (this.remoteSearchValue[code] == '') {
this.remoteSearchOptions[code] = []
}
this.search()
},
网友评论