后端根据前端给的parentId来返回它子级空间,我这里先入为主的想到树形结构应该自己写个递归去操作,根据父级id在树形结构中递归去找到相对应的对象,再把从后端获取的数据放进该对象的children数组中去,结果写出来后发现不仅代码量大,性能也不行,改用element-plus里面的el-cascader、el-tree-select自带的resolve方法进行树形结构转换。
后端返回数据结构:
[{ "deleteFlag": "0", "deleteTime": null, "rowState": "", "id": "xxxx", "orgId": "xxxx", "parentItemList": [ { "parentId": "0", "parentFlag": true, "hierarchy": 0 } ], "name": "测试(不要绑定设备)", "pinyin": "cs bybdsb", "hierarchy": 1, "serialNo": 0, "subNumber": 0, "spaceType": "Custom", "objectId": "", "objectName": "", "orgCode": "master", "spaceTypeText": "自定义", "spacePathText": "测试(不要绑定设备)", "parentId": "0" }]
这里傻乎乎的用了递归(其它代码就不放了,放了个递归代码在这)
<el-form-item label="地点" prop="spaceList"> <el-cascader v-model="formData.spaceList" @change="handleCascderChange($event)" class="w-full" :options="cascaderSpaceList" :props="cascadeProps" clearable > </el-form-item> // #region 方法 function handleFindObjectByParentId(parentId: string, list: any[]) { for (let i = 0; i < list.length; i++) { const item = list[i]; if (item.value == parentId) { return item; // 找到parentId对象 } if (item.children && item.children.length > 0) { const result: any = handleFindObjectByParentId(parentId, item.children); if (result) { return result; // 从子级中找到 } } } }
这里用 el-tree-select的原因是公司的空间层级不做限制,十几层的空间树,最后导致屏幕宽度都放不下展开后的级联。
<el-tree-select class="w-full" :check-strictly="true" :render-after-expand="false" show-checkbox v-model="formData.space" :default-expanded-keys="formData.spaceList" lazy :load="handleLoad" :props="treeSelectProps" :render-content="renderContent" > </el-tree-select> // 表单属性 const formData: FormData = reactive({ id: '', number: '', name: '', spaceList: [], // 用于tree-select的回显 space: '', // tree-select绑定值 enableFlag: '1', inOutMode: 'In', remark: '', parameterSetting: '', }); // #region 树的配置 const treeSelectProps = { value: 'value', label: 'label', children: 'children', isLeaf: 'isLeaf', }; // 自定义内容 const renderContent = (h: any, { data }: any) => { return h('span', data.name); }; const handleLoad = (node: any, resolve: any) => { const spaceId: any = node?.level == 0 ? '0' : node.data?.value; if (node.isLeaf) return resolve([]); handleGetSpaceListByPid(spaceId, resolve); }; // #endregion // #region 获取空间方法 function handleGetSpaceListByPid(parentId: string, resolve: any): void { IotAccess.getSpaceListByPid(parentId).then((res) => { if (res) { let nodes = Array.from(res).map((item: any) => ({ value: item.id, label: item.spacePathText, name: item.name, })); resolve(nodes); } }); } // #endregion
结语:果然写之前还是得思考一下多种写法,像这种先入为主写递归的,要是一开始想到用级联和树选择的懒加载就不用兜弯路了,菜鸡前端记录自己的项目经历。