记录 el-cascader 较多二级数据的处理

2,644 阅读2分钟

这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

写在前面

这是之前开发中遇到的问题,筛选选项中有一栏为选择标签。标签数据是一次性返回的,标签数据本身只有两级:一级标签分类,二级标签数据。二级标签数据会出现返回几千条的情况。单独多选几个标签本身不会有太大问题,但出现选中某个标签分类时,页面会有明显卡顿。

分析

减少页面中实际渲染的标签数

默认每个二级标签数据只加载前200个。
页面初始化绑定滚动事件,向上滚动距离 + 展示框高度 > 选项实际高度时即滚动到底。此时需要在该标签分类下判断数据是否加载完毕,若没有全部加载完则 option 拼接下页数据 200 或剩余数据,并在数据在页面渲染完成后滚动到对应位置 dom.scrollTo(0, scrollTop)

    const Cascader_DOM_warp = Cascader_DOM.getElementsByClassName('el-cascader-menu__wrap')[0]
    // 绑定滚动事件;
    Cascader_DOM_warp.addEventListener('scroll', function (event) {
      let e = event.target;
      if (e.scrollTop + Math.ceil(e.getBoundingClientRect().height) >= e.offsetHeight) {
        // 节流;
        if (this.timer) {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(() => {
          _this.loadMore(Cascader_DOM_warp, e.scrollTop)
        }, 50)
      }
    })

搜索时拼接标签数据

实际用户使用过程中会用到模糊搜索。若不做后续处理,当前标签未渲染出来的选项是搜索不出来的。
在默认筛选钩子调用前 before-filter:备份当前标签数据。调用后台并把对应每组下的标签查询结果拼入。注意返回为 Promise, resolve(options拼接结果)。
用户选完后关闭若把标签数据还原,不在该标签内的数据会自动被清空。

    beforeFilterEnterpriseLabel(name) {
      this.companyTags
      let params = {
        name
      }
      return new Promise((resolve, reject) => {
        http
          .searchCompanyTag(params)
          .then((res) => {
            this.lastCompanyTags = JSON.parse(JSON.stringify(this.companyTags))
            let filterArr = []
            res.data.forEach((item) => {
              item.label = item.group_name
              item.value = item.group_name
              item.group_list.forEach((tagItem) => {
                tagItem.label = tagItem.label_name
                tagItem.value = tagItem.id
              })
              item.children = item.group_list
              // 新查出来在哪个标签组
              // 标签组下children合并
              let i = this.casLevel0KeyArr.indexOf(item.value)
              item.children.forEach((searchItem) => {
                if (
                  JSON.stringify(this.companyTags[i].children).includes(
                    `${searchItem.label}`
                  )
                ) {
                } else {
                  let arr = [...this.companyTags[i].children, searchItem]
                  this.companyTags[i].children = arr
                }
              })
            })
            resolve(this.companyTags)
          })
          .catch(() => {})
      })
    }

还存在的问题:一是标签渲染一直滚动还是会出现过多的问题。二是若用户搜索选择后再次进入并滚动触发加载,可能会出现同一个选项 value, tag 出现两次的情况。
遗留问题后续看看怎么解决吧。。。欢迎大家给我点提示和思路。😢