今天产品让我给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,可以尝试这两个改动。

GitHub 加速计划 / eleme / element
11
1
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:9 个月前 )
c345bb45 1 年前
a07f3a59 * Update transition.md * Update table.md * Update transition.md * Update table.md * Update transition.md * Update table.md * Update table.md * Update transition.md * Update popover.md 1 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐