vue 树形选择器数据处理 + 搜索查询时每一层级都可选
vue 树形选择器
主要用后端处理显示数据
-
根据 el-Element 官网可知,想要使用树形选择器
<el-tree-select>
就要提供以下形式的数据:data = [ { value: '1', label: 'Level one 1', children: [ { value: '1-1', label: 'Level two 1-1', children: [ { value: '1-1-1', label: 'Level three 1-1-1', }, ], }, ], }, ...... ]
-
这里本人采用的方法是后端对数据做好处理,即直接向前端提供上述的 data 的结构样式:
-
首先建立好所需的树的实体类,主要用到了三个属性:树的编号
treeCode
、树的父编号treeParentCode
、树的名称treeName
、树的子树List<GoodsTree> childrenList
-
编写操作为树所需数据的结构:
// 查所有的tree数据,并整合成前端el-tree-select所需形式: // 取所有的 List<GoodsTree> allTree = goodsTreeService.selectTree(null); // 存顶层的数据 List<GoodsTree> resultTree = new ArrayList<>(); // 存所有的数据 Map<Object ,GoodsTree> treeMap = new HashMap(); // 存顶层的键 List<String> PCodeList = new ArrayList<>(); for (int i = 0; i < allTree.size() && !allTree.isEmpty(); i++){ // 把所有的数据都放到map中,(code, GoodsTree)的样式 treeMap.put(allTree.get(i).getTreeCode(), allTree.get(i)); } // 循环给父赋childrenList值 for (int i = 0; i < allTree.size() && !allTree.isEmpty(); i++) { GoodsTree goodsTrees = treeMap.get(allTree.get(i).getTreeParentCode()); if (goodsTrees != null) { // 找到父(注意,此处的i为子,allTree.get(i).getTreeParentCode()是为了找到父code) PCodeList.add(goodsTrees.getTreeCode()); // 存下父的code if (goodsTrees.getChildrenList() == null){ // 若还没有子,就先初始化 goodsTrees.setChildrenList(new ArrayList<>()); } goodsTrees.getChildrenList().add(allTree.get(i)); // 把i子放进父childrenList中 treeMap.put(allTree.get(i).getTreeParentCode(), goodsTrees); // 跟新父 } } // 过滤重复的code List<String> newList = PCodeList.stream().distinct().collect(Collectors.toList()); // 只获取父的那部分(子已经都包含在了父的childrenList中) for (int i = 0; i < newList.size() && !newList.isEmpty(); i++){ if(treeMap.get(newList.get(i)).getTreeParentCode() == null){ resultTree.add(treeMap.get(newList.get(i))); } }
- 实测方法可行,但是要循环三遍,如有更好的方法或优化还望赐教
-
前端获取:
const goodsTreeList = ref([]) const getTree = () => { goodsTreeApi.getAllTree((res) =>{ // 注意,直接获取不可行,还要化code为value,化name为label,化childrenList为children,要严格遵守格式 goodsTreeList.value = res.data; }) } // 以下才是正确的处理方法: /** * 树的获取 */ const goodsTreeList = ref([]) // 商品树 const getTree = () => { goodsTreeApi.getAllTree((res) =>{ goodsTreeList.value = changeData(res.data); }) } const changeData = (data) => { return data.map((item) => { const newItem = { label: item.treeName, value: item.treeCode, }; if (item.childrenList) { // 如果有子,那就再处理子 newItem.children = changeData(item.childrenList); // 递归过程 } return newItem; }); };
-
前后端都处理后,树形选择器的数据属性就可以直接写了:
:data="goodsTreeList"
-
实现树形每一级都可选
-
功能场景:一般样式就是点击一层级或二层级后只会展开其子数据,即若是根据所选查询,就只能根据最下面的叶层级的来查询
- 即只能选黄岛、历城,不能选中青岛、济南
-
但是这里想要做到每一级都可获取,即:选黄岛就只表格显示黄岛的,选青岛就表格显示市南区、市北区、黄岛区、崂山区、李沧区、城阳区、即墨区所有的信息(甚至到市北的纺织谷,只要有子,就都能查到)
-
我这里用的是比较基础的,最笨的方法(秉着能用就行,能跑就管的思想~),有更好的方法还请赐教
-
这里先提供思路:
-
根据父找子信息
-
递归再找每个子下的子信息
-
方法就不再细讲,代码如下:
/** * 根据父取所有父子code集合List * @param goodsTree * @return */ public List<String> selectByTree(GoodsTree goodsTree) { String treeCode = goodsTree.getTreeCode(); if (!(treeCode.isEmpty())){ // 存treeCode下所有code List<String> childrenCode = new ArrayList<>(); childrenCode.add(treeCode); // 是某个的父树 if (judge(goodsTree)){ // 遍历方法 allChildTree(goodsTree, childrenCode); // 获取到存所有的code的list } return childrenCode; } return null; } /** * 判断是否有子 * @param goodsTree * @return */ public boolean judge(GoodsTree goodsTree) { // 查有没有以此为父的子树 List<GoodsTree> goodsTrees = selectTree(goodsTree); if (goodsTrees.size() == 0){ return false; } else { return true; } } /** * 遍历取所有子树code * @param fuTree 父code * @param childrenCode 父子code集合 * @return */ public List<String> allChildTree(GoodsTree fuTree, List<String> childrenCode) { // 取所有直接的子树 List<GoodsTree> goodsChildTree = selectTree(fuTree); if (goodsChildTree != null){ for (int i = 0; i < goodsChildTree.size(); i++) { GoodsTree goodsTree1 = goodsChildTree.get(i); childrenCode.add(goodsTree1.getTreeCode()); allChildTree(goodsTree1, childrenCode); } } return childrenCode; }
-
返回的
childrenCode
里就是所有的需要的 code 值
-
-
树形选择器的编写还是参考官网 https://element-plus.org/zh-CN/component/tree-select.html,描述的很清楚
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义