今天产品让我给cascader级联选择器加个可搜索,我寻思这还不简单,直接加个filterable就行了。结果因为这个cascader使用了懒加载来进行多层级的请求,filterable并不能正常使用,输入什么都显示没有数据。
麻烦的是change事件也完全不响应这个搜索值的变化,只会在组件有选中项的时候触发。查询资料后,我找到这个属性:
这个钩子函数里能获取filterable的搜索值,并通过return true或false来开启或关闭默认的搜索行为。可有个问题是beforeFilter在搜索值为空时也不会触发,最终我只好通过监听里面input框的dom来实现搜索的清空还原。
注意:element-plus的el-cascader有两个input框,经实践el-cascader__search-input才是能取到搜索词的框。如果你用的element-ui版肯定会有区别。
完整方案如下:
<el-cascader class="user-cascader" ref="classify" v-model="data.curItem2"
:options="data.options2" :props="data.props2" @change="handleChange2" filterable clearable :before-filter="beforeFilter" />
onMounted(() => {
// 获取data.options2 并备份一个data.options2Copy
// getList()
// 监听搜索框的dom
nextTick(() => {
let dom = document.getElementsByClassName('user-cascader')[0]
let inputDom = dom.getElementsByClassName('el-cascader__search-input')[0] // 搜索框
inputDom.addEventListener('input', (e) => {
console.log(e.target.value)
const value = e.target.value
if (!value) {
clear()
}
})
})
});
function beforeFilter(value) {
data.keyWord = value?.trim()
console.log(data.keyWord)
// 手动筛选
data.options2 = data.options2.filter(v => v.label.indexOf(data.keyWord) > -1)
// 空的时候显示默认的筛选无结果面板
if (data.options2.length === 0) {
return true
}
// 懒加载时默认筛选无效 直接禁用它 让组件加载我们手动筛选的数据
return false
}
// 没搜索词时展示完整的原列表数据
const clear = () => {
data.keyWord = ''
data.options2 = JSON.parse(JSON.stringify(data.options2Copy))
}
另外看其他资料element-ui版需要加上:key来手动刷新组件,另一个区别就是input的类名,其他思路逻辑都是一致的。如果你看到了这篇文章但是用的element-ui,可以尝试这两个改动。