使用elementUI级联选择器懒加载,从后台获取到级联选择内容后如何正确回显?

目前项目有一个输入框内容是需要选择行业类型,
按国标分类有门类大类中类小类四项内容,为了避免使用四个input输入框因此采用了elementUI的级联选择器。
然后因为每一小类要在选择了上级类型后调取接口获取数据,因此采用了官方给出的懒加载操作。
实现级联选择很简单

props: {

    value: 'BIANMA',
    label: 'NAME',
    lazy: true,
    lazyLoad (node, resolve) {
      if (node.path) {
        node.path.length == 1 && listindustryMedium(node.path[0]).then(response => {
          resolve(response.data);
        });
        node.path.length == 2 && listindustryMedium(node.path[1]).then(response => {
          resolve(response.data);
        });
        node.path.length == 3 && listindustryMedium(node.path[2]).then(response => {
          response.data.forEach(item => {
            item.leaf = 'leaf';
          })
          resolve(response.data);
        });
      }
    }
  },
  // 级联绑定的树是 trades;

当前的做法就是根据路径深度请求下一级选项,如果已经是小类了就加上叶子节点leaf的判断。

但是因为后台数据库分为门类大类中类小类四个字段存储;
所以提交时需要拆分,从后台获取时需要重新组合。
组合完后又因为当初设计必须选择上一级才会请求下一级菜单。
因此在修改时,仅仅从后台获取到value,无法在前端展示label。

我想到的方法是根据四级value,分别通过接口获取label数据,模拟生成一颗只含有后台返回的四级分类路径的树

this.tradesKind = response.data.tradesKind;

    this.tradesBig = response.data.tradesBig;
    this.tradesMid = response.data.tradesMid;
    this.tradesSmall = response.data.tradesSmall;
    this.$set(this.form, 'trades', [this.tradesKind, this.tradesBig, this.tradesMid, this.tradesSmall])
    listindustryMedium(response.data.tradesKind).then(response => {
      this.cstTradesTypeOptions = response.data; //原行业大类下拉框
      this.trades.forEach(item => {
        item.BIANMA == this.tradesKind && this.$set(item, 'children', this.cstTradesTypeOptions)
      });
    });
    listindustryMedium(response.data.tradesBig).then(response => {
      this.cstTradesMediumOptions = response.data; //原行业中类下拉框
      this.trades.forEach(item => {
        item.BIANMA == this.tradesKind && item.children.forEach(item => {
          item.BIANMA == this.tradesBig && this.$set(item, 'children', this.cstTradesMediumOptions)
        });
      });
    });
    listindustryMedium(response.data.tradesMid).then(response => {
      this.cstTradesSmallOptions = response.data; //原行业小类下拉框
      this.trades.forEach(item => {
        item.BIANMA == this.tradesKind && item.children.forEach(item => {
          item.BIANMA == this.tradesBig && item.children.forEach(item => {
            item.BIANMA == this.tradesMid && this.$set(item, 'children', this.cstTradesSmallOptions)
            item.children.forEach(item => {
              this.$set(item, 'leaf', 'leaf')
            });
          });
        })
      })
    });

但是这种方式首先他可读性非常差,后来人看到这个估计直接想提刀砍死我。更重要的是这个方式构建的树不稳定啊。我测试的时候发现,经常有某几个选项是能够正确回显的。但是某几项会卡在某个节点,添加不进获取到的children节点。经测试不是异步请求的问题,因此我也不太清楚哪一步出错了。

针对这种懒加载级联选择器 + 回显的需求
有什么更好的方案或者说我当前方式该从哪里优化?

阅读 7.3k
1 个回答

简单实现动态级联的显示,供你参考,看是否能解决你的问题

data() {
  return {
    props: {
      lazy: true,
      lazyLoad: async (node, resolve) => {
        let a = await this.lazyLoadNode(node)
        resolve(a)
      }
    }
  };
},
methods: {
    lazyLoadNode(node) {
        const { level } = node;
        // 以下是判断请求下一层级的数据请求
        // 建议可以使用变量保存起来,以便下一次直接使用变量不在发送请求
        switch(level) {
            case 0:
                // TODO: 门类请求
                break
            case 1:
                // TODO: 大类请求
                break
            case 2:
                // TODO: 中类请求
                break
            case 3:
                // TODO: 小类请求
                break
            default:
                // 默认可以设置为门类请求
                break
        }
        // 模拟请求,这个根据实际项目就放在switch中
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                const nodes = Array.from({ length: level + 1 })
                .map(item => ({
                    value: ++id,
                    label: `选项${id}`,
                    leaf: level >= 2
                }));
                resolve(nodes)
            }, 1000);
        })
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题