怎么做一个支持模糊搜索且保存原结构定位的级联地区选择器?

140 阅读2分钟

模糊搜索定位 地区选择器

需求介绍

大家好,我是一个编程小白。我的美女老板给我布置了一个任务,要求优化现有的地区级联选择器。她觉得当前的组件使用体验不佳,主要有两个问题:

  1. 不能模糊搜索:销售只是从别人那里听的一个地区但是不知道是哪几个字,没法搜。
  2. 为什么不能直接定位:希望直接定位到某个市级并在县级中选择,而不是弹出一个搜索结果窗口。

作为一个编程小白,不好意思拒绝这个合理的要求,于是我尝试寻找现成的解决方案的组件,但未能如愿。我又想能不能修改一下源码,发私包,但是考虑到修改源码的工程量过大,属于下下策了,于是特来掘金寻找答案?

附上我的解决方案

1. 实现模糊搜索

这个比较简单,可以通过拼音和原属性的结合实现模糊搜索:

const filterOption = (inputValue: string, option: any) => {
  // 将选项名称转换为拼音
  const pinyinName = pinyin(option.name, {
    toneType: 'none',
    type: 'array',
  }).join('')

  // 检查输入值是否在选项名称或其拼音中
  return (
    option.name.includes(inputValue) ||
    pinyinName.includes(inputValue.toLowerCase())
  )
}

2. 实现搜索结果定位

直接定位的时候,不出筛选结果弹窗。为啥会有筛选弹窗?可能是方便看结果吧。
我的思路是:
1.首先让他不出搜索弹窗
2.在原弹窗的位置匹配搜索结果的第一项,并让他展开并滚动到当前位置。
有了思路后直接看代码

源代码如下

image.png 于是我直接把这个cascader组件copy到我的代码里直接修改

      const showSearchPanel = computed(
        () => false
        // props.allowSearch && computedInputValue.value.length > 0
      )

然后在引用的地方增加如下代码

  // 定位并展开下一级
  const locateAndClickOption = async (
    panel: Element,
    columnIndex: number,
    optionName: string
  ) => {
    const column = panel.getElementsByClassName('arco-cascader-panel-column')[
      columnIndex
    ]
    const option = column.querySelector(
      `li[title="${optionName}"]`
    ) as HTMLElement
    const scrollbar = column.querySelector('.arco-scrollbar-container')

    if (scrollbar && option) {
      scrollbar.scrollTo({
        top: option.offsetTop,
      })
      if (columnIndex < 2) option.click()
    }
  }

  // 自定义搜索
  const handleRegionSearch = async (value: string) => {
    if (!value || !cascaderRef.value.filteredLeafOptions?.length) return

    const panel = document.querySelector(`.${contentClass}`)
    if (!panel) return

    const { pathValue } = cascaderRef.value.filteredLeafOptions[0]

    // 依次定位省市县
    pathValue.forEach((name: string, i: number) => {
      nextTick(() => {
        locateAndClickOption(panel, i, name)
      })
    })
  }


思路链接

github.com/LeonsCd/chi…
当然主要还是来找答案。