首页 > 其他分享 >vue 树形选择器数据处理 + 搜索查询时每一层级都可选

vue 树形选择器数据处理 + 搜索查询时每一层级都可选

时间:2023-12-05 23:25:10浏览次数:27  
标签:allTree code return childrenCode get List 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 的结构样式:

    1. 首先建立好所需的树的实体类,主要用到了三个属性:树的编号 treeCode、树的父编号 treeParentCode、树的名称 treeName、树的子树 List<GoodsTree> childrenList

    2. 编写操作为树所需数据的结构:

      // 查所有的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)));
          }
      }
      
      • 实测方法可行,但是要循环三遍,如有更好的方法或优化还望赐教
    3. 前端获取:

      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;
          });
      };
      
    4. 前后端都处理后,树形选择器的数据属性就可以直接写了::data="goodsTreeList"

实现树形每一级都可选

  • 功能场景:一般样式就是点击一层级或二层级后只会展开其子数据,即若是根据所选查询,就只能根据最下面的叶层级的来查询

    • 即只能选黄岛、历城,不能选中青岛、济南
  • 但是这里想要做到每一级都可获取,即:选黄岛就只表格显示黄岛的,选青岛就表格显示市南区、市北区、黄岛区、崂山区、李沧区、城阳区、即墨区所有的信息(甚至到市北的纺织谷,只要有子,就都能查到)

  • 我这里用的是比较基础的,最笨的方法(秉着能用就行,能跑就管的思想~),有更好的方法还请赐教

  • 这里先提供思路:

    1. 根据父找子信息

    2. 递归再找每个子下的子信息

    3. 方法就不再细讲,代码如下:

      /**
       * 根据父取所有父子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;
      }
      
    4. 返回的 childrenCode 里就是所有的需要的 code 值

  • 树形选择器的编写还是参考官网 https://element-plus.org/zh-CN/component/tree-select.html,描述的很清楚

标签:allTree,code,return,childrenCode,get,List,vue,树形,选择器
From: https://www.cnblogs.com/zhu-ya-zhu/p/17878561.html

相关文章

  • 树的中心——树形dp/换根dp启蒙
    请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。这个点被称为树的中心。题解:https://www.cnblogs.com/dx123/p/17302104.html评测:https://www.acwing.com/problem/content/1075/暴力做法是以每个点为根,求出从根向下走的最远距离,这个过程需要做n遍,每一遍dfs的复杂......
  • 树的直径——树形dp求法
    树上任意两节点之间最长的简单路径即为树的「直径」。树形DP的做法可以在存在负权边的情况下求解出树的直径。constintN=10010,M=20010;intn,a,b,c,ans;structedge{intv,w;};vector<edge>e[N];intdfs(intx,intfa){intd1=0,d2=0;for(autoed:e[x]){......
  • uniapp 微信小程序 onLaunch触发vuex 请求http报错600009?
    当在uniapp中的微信小程序中使用vuex触发http请求时,出现错误码600009通常表示网络请求发生了错误或失败。这个错误码通常不是uniapp或vuex特定的错误码,而是微信小程序的错误码。以下是一些可能导致此错误的原因和解决方法:网络连接问题:首先,确保您的设备已连接到互联网,并且网络连接稳......
  • 记录--Vue使用CDN引入,响应式失效?
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助背景最近心血来潮,想要在本地开发时,也用CDN的方式引入Vue,想着既然通过CDN引入了,那么在项目中就没必要再importVue,然后把项目中引入Vue的地方都删掉,结果改完后,界面看似正常运行,但数据变更后,界面没有重新渲染。......
  • vue3使用虚拟化表格自定义表格并动态生成表头
    elementPlus的虚拟化表格用的是lang=tsx,先安装cnpmi@vitejs/plugin-vue-jsx然后去vite.config.ts里加配置importvueJsxfrom'@vitejs/plugin-vue-jsx'plugins:[vue(),vueJsx(),]再去tsconfig.json中加东西//不要把compilerOptio......
  • vue项目:如何在编辑用户信息后,能够及时更新layout下的navar组件中的用户名,而不是手动刷
    问题描述:layout下的navar组件中展示用户名,初始化时进入layout层会进入mouted中请求接口数据展示名称,但是在编辑弹框中编辑成功后,关闭弹框,此时不会走layout的mouted,因为layout组件的mouted已经加载过一次了,不手动刷新浏览器是不会走mouted生命周期的。那怎么解决这个不能及时更新数......
  • vue中引用utils中的方法
    utils中的目录解构如下(utils在src目录下),以深拷贝为例:deepClone文件的代码如下:functiondeepClone(substance){if(typeofsubstance!=='object'||substance==null){returnsubstance;}constresult=Array.isArray(substance)?[]:{};for(constkey......
  • 计算机毕业设计springcloud vue商城源码
    开发环境及工具:大等于jdk1.8,大于mysql5.5,idea(eclipse),nodejs,vscode(webstorm)技术说明:springcloudspringbootmybatisvueelementui代码注释齐全,没有多余代码,适合学习(毕设),二次开发,包含论文技术相关文档。功能介绍:用户端:登录注册首页显示搜索商品,轮播图,商品分类,点击分类展示对应商,(......
  • 解决vue-django配置问题
    后端跨域问题django安装pipinstalldjango-cors-headers添加应用,主应用下的settingINSTALLED_APPS=[...#跨域'corsheaders',...]中间件设置MIDDLEWARE=[...#跨域中间键设置'corsheaders.middleware.CorsMiddleware', ...]添加黑白名单(se......
  • vue的响应式原理:依赖追踪
    在明白原理之前,我们有很多表面现象、使用场景需要记忆。明白了原理后,你会发现它们已经不需要记了,因为从原理出发,你自己都能把它们推导出来,一切是那么的自然而然。感觉就是:这还用记吗?很明显嘛!之前我对vue的响应式原理,只是一知半解,导致开发中经常会出现疑问,比如:为什么有的数据它不......