jeecgboot-vue3筆記(九)——treeSelect樹形選擇元件的使用(非同步載入)

2022-05-30 21:00:41

使用效果


初始化載入頂層節點,點選各層的>載入該節點的子節點,載入後>標識去除不再重複載入。

前端程式碼

vue ant-design元件

  • tree-data,樹節點,children方式或id、pid方式
  • load-data,展開節點事件,響應該事件載入子節點
<a-tree-select v-model:value="sample" :tree-data="sampleTreeData" :load-data="onLoadSampleTreeData"
        style="width: 100%" allowClear treeDataSimpleMode 
        :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
        placeholder="請選擇測試計劃/樣品" >                           
</a-tree-select>

定義interface

  • 非同步載入通過id和pid匹配,因此沒有children屬性,替換為id何pid
  • 新增level便於後端識別,如果後端為一個表內的資料且通過id和pid或parentid關聯則不需要
export interface TreeDataItem {
  id: string | number;
  pId: string | number;
  value: string;
  title: string;
  isLeaf?: boolean;
  level: string;
}

載入(跟節點)資料

呼叫後端查詢資料並賦值給treeData,treeData繫結控制元件的treeData屬性。

async function loadSampleTreeRootData() {
  // loading.value = true
  let params = {"level":"0"};
  sampleTreeNode(params).then(result => { 
      console.log(result)
      sampleTreeData.value = sampleTreeData.value.concat(result);
      }).finally(() => { 
      });
  // loading.value = false  
}
loadSampleTreeRootData()

載入(節點的子節點)資料

響應控制元件的load-data事件,查詢要展開節點的子節點資料,併合併到treeData中,控制元件會根據id和pid顯示層級關係。

const onLoadSampleTreeData = (treeNode: any) => { 
      return new Promise((resolve: (value?: unknown) => void) => {
        // console.log("node:");
        // console.log(treeNode.dataRef)
        const { id,level,value } = treeNode.dataRef; 
        // console.log("id:"+id);
        // console.log("level:"+level);
        // console.log("value:"+value); 
        setTimeout(() => { 
            let nextLevel = "1";
            if(level=="1")nextLevel="2";
            let params = {"level":nextLevel, "id":id}; 
            sampleTreeNode(params).then(result => { 
            //    console.log("result:");
            //    console.log(result); 
                sampleTreeData.value = sampleTreeData.value.concat(result); 
            }).finally(() => { 
            }); 
          resolve();
        }, 300);
      });
    };

後端程式碼

定義treeNodeVO

pId和isLeaf註解下,避免springMVC預設的序列化。
(預設序列化為pid\leaf)

@Data
public class PlantSampleTreeNodeVO {
    //key
    private String id;
//    private long id;

    @JsonProperty("pId")
    private String pId;
//    private long pId;

    //樹節點顯示的內容
    private String title;

    //預設根據此屬性值進行篩選(其值在整個樹範圍內唯一)
    private Object value;

    //是否是葉子節點
    @JsonProperty("isLeaf")
    private boolean isLeaf;

    //節點層級
    private String level;

}

controller提供資料

因為是非同步載入,三個表的查詢可在一個service中實現,或直接使用各自的treeNode的service。

@Override
	public List<PlantSampleTreeNodeVO> getPlantSampleTreeNodeVO(String level, String id) {
		List<PlantSampleTreeNodeVO> plantSampleTreeVONodeList = new ArrayList<>();
		switch (level) {//頂級節點
			case "0":
				//查詢所在班組,plant member
				List<Plant> plantList = plantService.list();
				for (Plant plant : plantList) {
					//建立頂層樹/節點
					PlantSampleTreeNodeVO plantNode = new PlantSampleTreeNodeVO();
//					System.out.println(plant.getId());
//					System.out.println(Long.parseLong(plant.getId()));
//					System.out.println(Long.valueOf(plant.getId()).longValue());
//					plantNode.setId(Long.parseLong(plant.getId()));
					plantNode.setId(plant.getId());
					plantNode.setPId("0");//and-design tree指定的值
					plantNode.setValue(plant.getId());
					plantNode.setTitle(plant.getPlantName());
					plantNode.setLeaf(false);//需根據業務邏輯判斷是否有子節點,省略處理
					plantNode.setLevel("0");
					plantSampleTreeVONodeList.add(plantNode);
				}
				break;
			case "1":
				//查詢班組相關的樣品組模板
				QueryWrapper<SampleGroupTemplate> sampleGroupTemplateQueryWrapper = new QueryWrapper<>();
				sampleGroupTemplateQueryWrapper.eq("plantid",id);
				List<SampleGroupTemplate> sampleGroupTemplateList = sampleGroupTemplateService.list(sampleGroupTemplateQueryWrapper);
				//迴圈各樣品組模板顯示其下的測試計劃/樣品
				for(SampleGroupTemplate sampleGroupTemplate: sampleGroupTemplateList){
					//新增到樹上
					PlantSampleTreeNodeVO sampleGroupNode = new PlantSampleTreeNodeVO();
//					sampleGroupNode.setId(Long.parseLong(sampleGroupTemplate.getId()));
					sampleGroupNode.setId(sampleGroupTemplate.getId());
//					sampleGroupNode.setPId(Long.parseLong(id));
					sampleGroupNode.setPId(id);
					sampleGroupNode.setValue(sampleGroupTemplate.getId());
					sampleGroupNode.setTitle(sampleGroupTemplate.getSampleGroupName());
					sampleGroupNode.setLeaf(false);
					sampleGroupNode.setLevel("1");
					plantSampleTreeVONodeList.add(sampleGroupNode);
				}
				break;
			case "2":
				//查詢樣品組模板顯示其下的測試計劃/樣品
				QueryWrapper<SgtSample> sampleQueryWrapper = new QueryWrapper<>();
				sampleQueryWrapper.eq("templateid",id);
				List<SgtSample> sampleList = this.list(sampleQueryWrapper);
				//迴圈各樣品
				for(SgtSample sample: sampleList) {
					PlantSampleTreeNodeVO sampleNode = new PlantSampleTreeNodeVO();
//					sampleNode.setId(Long.parseLong(sample.getId()));
					sampleNode.setId(sample.getId());
//					sampleNode.setPId(Long.parseLong(id));
					sampleNode.setPId(id);
					sampleNode.setValue(sample.getId());
					sampleNode.setTitle(sample.getSampleName());
					sampleNode.setLeaf(true);//葉子節點
					sampleNode.setLevel("2");
					plantSampleTreeVONodeList.add(sampleNode);
				}
				break;
		}
		return plantSampleTreeVONodeList;
	}