天天看点

spring boot实践系列9——el-cascader异步加载解决方案

作者:晖晖yyds
spring boot实践系列9——el-cascader异步加载解决方案

1、问题描述

省市区多级菜单使用el-element的控件Cascader 级联选择器,一次加载全部数据,需等待1秒多,体验较不好。实现界面效果如下:

spring boot实践系列9——el-cascader异步加载解决方案

2、解决方案

查看官方文档,通过lazy参数来开启动态加载,并通过lazyload来设置加载数据源的方法。lazyload方法有两个参数,第一个参数node为当前点击的节点,第二个resolve为数据加载完成的回调(必须调用)。官方栗子如下图如示:

spring boot实践系列9——el-cascader异步加载解决方案

在以上的栗子中,设置lazy属性为true,通过lazyload方法来设置数据源,最终通过resolve方法将数据返回。

3、项目实战

3.1、cascader取值显示

前端代码:

设置cascader属性,这里需注意v-model的传值,v-model值需设为数组,形如:[120000, 120100, 120101]这样的形式,保存操作传参时,如只需存储最后一位,要特殊处理;回显时,同样需组装形如[120000, 120100, 120101]的数据,才能正确显示。

<el-cascader v-model="form.areaTran" :props="areaProps" :show-all-levels="false"></el-cascader>           

areaProps属性设置如下:

areaProps: {
  lazy: true,
  checkStrictly: true,
  lazyLoad: this.loadAreaTree,
},
loadAreaTree(node, resolve) {
  // 首次加载时 node为{root:true,level:0}
  // node 节点数据 获取node的level字段的值
  const { level } = node;
  //下一层节点
  const nodes = [];
  if (node.hasChildren || node.root) {
    // 0 代表第一次请求
    let nodeId = level == 0 ? 1 : node.value;
    //这里setTimeout的目的是 显示加载动画  
    setTimeout(() => {
    //调用后端接口 获得返回数据
    let ret = listAreaByPId({parentId:nodeId});
    listAreaByPId({parentId:nodeId}).then(response => {
      const childNodes = response.data.map((item) => ({
        value: item["areaId"],
        label: item["areaName"],
        leaf: level>= 2,
      }));
    return resolve(childNodes);
  });
  }, 1);
} else {
//如果没有子节点就不发起请求,直接渲染,也避免了点击叶子节点仍然有加载动画的问题
  resolve(nodes);
}
}           

以上代码都有说明注释,不多说明,注意一点的是leaf属性,当leaf>=2时,为叶子节点,不会继续发请求了,否则还要再请求一次,体验不太好。

后端代码:

@ApiOperation("根据PId查询地区管理列表")
@PreAuthorize("@ss.hasPermi('basicinfo:area:list')")
@GetMapping("/listByPId")
public AjaxResult listByPId(Area area)
{
     List<Area> list = areaService.selectAreaList(area);
     return success(list);
}           

后端代码比较简单,只是根据PId查询下一级的数据。

3.2、cascader回显

后端代码:

当我们需要修改数据时,点击修改打开的弹窗中要正确回显到已经保存好的区域。这边前端代码无需修改,主要是后端代码修改,由于后端只存储某一节点的值,而前端需要的是完整的路径数组,所以后端要组装相应的数据。关键代码如下:

spring boot实践系列9——el-cascader异步加载解决方案

这里areas是全部区域数据,通过递归,返回前端所需要的数据格式。

通过组装VO返回前端:

@Data
public class TurfPitchVO extends TurfPitch {
    private ArrayList areaTran;
}           

3.3、保存操作

Save操作只需取最后一级传到前端即可。

// 取级联对象数组最后一级
if(this.form.areaTran.length>0){
  let curAreaId=this.form.areaTran[this.form.areaTran.length - 1];
  this.form.areaId=curAreaId;
}           

4、扩展剖析

查看官方文档,props的属性如下,可供参考:

spring boot实践系列9——el-cascader异步加载解决方案