【Vue】树状节点接口 与 级联选择框组件
原来有一个组织机构的渲染,
我自己写的我自己看也8太明白了:
1 | https: //www .cnblogs.com /mindzone/p/14888046 .html |
现在,有一个位置选择,使用这个级联选择器做的
1 | https: //element .eleme.cn/ #/zh-CN/component/cascader#cascader-ji-lian-xuan-ze-qi |
后台接口部分
首先是组件需要的节点数据结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package cn.ymcd.aisw.store.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.List; /** * 树状节点PO * @author cloud9 * @createTime 2022/5/18 09:55 * */ @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode (callSuper = false ) @Accessors (chain = true ) public class TreeNode implements Serializable { private static final long serialVersionUID = 1L; private String label; private Integer value; private List<TreeNode> children; public TreeNode(String label, Integer value) { this .label = label; this .value = value; } } |
数据库PO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | package cn.ymcd.aisw.store.dto; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; /** * 行政区域PO * @author cloud9 * @createTime 2022/5/18 09:57 * */ @Data @EqualsAndHashCode (callSuper = false ) @Accessors (chain = true ) @TableName ( "PT_AREA" ) public class AreaDTO implements Serializable { private static final long serialVersionUID = 1L; /** * 区域Id<br/> TYPE:NUMBER(22) */ @TableField ( "AREAID" ) private Integer areaid; /** * 区域编码<br/> TYPE:NUMBER(22) */ @TableField ( "AREACODE" ) private Integer areacode; /** * 区域名称<br/> TYPE:VARCHAR2(200) */ @TableField ( "AREANAME" ) private String areaname; /** * 区域等级<br/> TYPE:VARCHAR2(2) */ @TableField ( "AREALEVEL" ) private String arealevel; /** * 区域父级<br/> TYPE:NUMBER(22) */ @TableField ( "AREAPARENT" ) private Integer areaparent; /** * 区域序号<br/> TYPE:NUMBER(22) */ @TableField ( "AREASEQ" ) private Integer areaseq; /** * 是否可用<br/> TYPE:VARCHAR2(2) */ @TableField ( "ISENABLED" ) private String isenabled; } |
接口业务实现类,就是如何组装级联选择器需要的数据结构:
省市县,全部最多的情况是四千多个不到,使用这种递归,还是能处理的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | package cn.ymcd.aisw.store.service.impl; import cn.ymcd.aisw.common.ApiConstants; import cn.ymcd.aisw.store.dao.AreaDAO; import cn.ymcd.aisw.store.dto.AreaDTO; import cn.ymcd.aisw.store.dto.TreeNode; import cn.ymcd.aisw.store.service.IAreaService; import cn.ymcd.comm.base.BaseService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.List; import java.util.stream.Collectors; /** * @projectName: aisw-root * @author: cloud9 * @date: 2022年05月18日 10:02 * @version: 1.0 */ @Service ( "iAreaService" ) public class AreaServiceImpl extends BaseService<AreaDAO, AreaDTO> implements IAreaService { @Resource private AreaDAO areaDAO; @Override public List<TreeNode> getAreaCodeList() { // 筛选所有(可用的 -> isenabled = 1)区域列表 final List<AreaDTO> ALL_AVAILABLE_AREAS = areaDAO.selectList( new QueryWrapper<AreaDTO>() .lambda() .eq(AreaDTO::getIsenabled, ApiConstants.STATUS_NORMAL) ); // 筛选第一级区域的 TreeNode列表,此时每一个节点都没有子集 List<TreeNode> headerTreeNodes = ALL_AVAILABLE_AREAS .stream() .filter(area -> area.getAreaparent().equals( 0 )) .map(area -> new TreeNode(area.getAreaname(), area.getAreacode())) .collect(Collectors.toList()); // 然后对头的每个节点进行递归获取内部节点 headerTreeNodes.forEach(header -> buildTreeNodeWithRecursive(header, ALL_AVAILABLE_AREAS)); return headerTreeNodes; } /** * 使用递归进行树状节点集构建 * @param treeNode 需要被装填(若干层级)的节点 * @param ALL_AREA_LIST 树状节点的数据源 * @return void * @author cloud9 * @createTime 2022/5/18 11:53 * */ private void buildTreeNodeWithRecursive(TreeNode treeNode, final List<AreaDTO> ALL_AREA_LIST) { // 获取入参节点的的子节点列表, 从总集合中过滤 List<TreeNode> recursiveTreeNodeList = ALL_AREA_LIST .stream() .filter(area -> area.getAreaparent().equals(treeNode.getValue())) .map(area -> new TreeNode(area.getAreaname(), area.getAreacode())) .collect(Collectors.toList()); // 如果这子节点是最后一层了,也就是查不到子节点集合,则终止这个递归 if (CollectionUtils.isEmpty(recursiveTreeNodeList)) return ; // 1、否则继续下去, 将子节点存入这个节点下面 treeNode.setChildren(recursiveTreeNodeList); // 2、然后将这个子节点列表遍历, 获取它的后代 recursiveTreeNodeList.forEach(childTreeNode -> this .buildTreeNodeWithRecursive(childTreeNode, ALL_AREA_LIST)); } } |
前台渲染部分:
1 2 3 4 5 6 7 8 9 10 11 12 | < el-form-item label="门店位置" prop="areaName"> < el-cascader :ref="selectorRefTag" v-model="store.areaAddrs" placeholder="试试搜索:南昌" :props="{ value: 'label' }" :options="areaTreeNode" style="width: 220px" filterable @change="handleAreaSelectChange" /> </ el-form-item > |
数据来源,接口就是GET请求,不进行任何认证校验:
1 2 3 4 5 | async created() { const { data: res } = await getAreaTreeNodeList() console.log(res) this .areaTreeNode = res }, |
绑定的Change事件方法:
选中的数据会排在第一个,这里因为业务需要,我要的是路径标签
就是把这个PathLabels数组,转成拼接字符,也可以取PathValues取ID值
1 2 3 4 5 6 7 | handleAreaSelectChange() { // 获取选中的所有节点的路径,并且用join()方法分割转换为字符串 this .labels = this .$refs[ this .selectorRefTag] .getCheckedNodes()[0] .pathLabels.join( '' ) console.log( this .labels) }, |
回显的问题:
设置的v-model值就是绑定选中数据,所以回显的时候,把这个绑定值赋值上去即可
1 2 | /* 区域回显 */ if ( this .store.areaName) this .store.areaAddrs = this .store.areaName.split( ',' ) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2020-05-18 【Tutorial C】04 基本输入输出
2020-05-18 【Tutorial C】01 概述
2020-05-18 【Git】01 下载安装(Windows)
2020-05-18 【PL/SQL】05 异常处理
2020-05-18 【PL/SQL】04 游标 Cursor
2020-05-18 【PL/SQL】03 流程控制
2020-05-18 【PL/SQL】02 基础语法