Element UI CascaderPanel级联组件使用和踩坑总结

本文介绍了如何在项目中使用ElementUI的CascaderPanel组件实现多选功能,同时处理节点过滤和特殊情况下change事件的触发。重点提及了处理叶子节点和服务器返回数据的问题及解决方案。
摘要由CSDN通过智能技术生成

Element UI CascaderPanel级联组件使用和踩坑总结

问题背景

需求中需要用到Element UI的 CascaderPanel组件,并且支持多选,定制化需求,比如某节点被选择,等价于该节点下面所有子节点都被选择, CascaderPanel组件返回的选择数据为选择的所有节点,需要过滤到只返回到最上方被选中的层级。如图所示:
在这里插入图片描述

问题分析

(1)el-cascader-panel组件基本使用

                <el-cascader-panel ref="test" :options="myOptions" @change="handNodeChange('test')"  v-model="myOptionsSelectedAreas" 
                :props="{ multiple: true }">

(2)过滤所有节点,过滤方法:!(item.parent && item.parent.checked),即排除掉父节点存在且被选中的节点,得到过滤后的节点:

            // 监听级联组件数据变化,隐藏父组件选择状态下的子组件。
            handNodeChange(value) {
              let checkedNodeList = this.$refs[value].getCheckedNodes();
              checkedNodeList = checkedNodeList.filter(item => {
                return !(item.parent && item.parent.checked);
              });
              this[value] = checkedNodeList;
              this.myOptionsStandardSelectedAreas = [];
              checkedNodeList.forEach(item => {
                this.myOptionsStandardSelectedAreas.push(item.path.join('-'));
              });
            },

(3)坑:最后一级即叶子结点,也有children只不过children=[],这就导致组件无法确定最后一级,所以无法触发change事件。把叶子节点的children删除即可(该坑在Element Plus中测试已没有)。

          // 遍历得到需要的树结构
          dealNodeTree(node) {
            if (!node) {
              return null;
            }
            let temNode = this.changeNode(node);
            if (temNode.children) {
              // 处理children字段
              temNode.children = temNode.children.map(item => {
              return this.dealNodeTree(item);
            });
            }
            return temNode;
          },

(4)服务器返回的字符串,或者选中数组直到选中节点最高父级,需要获取所有选中的子节点,才能让级联组件正常显示。
dfs对根节点进行深度遍历,获取所有路径,存到全路径列表中,和最高级父节点进行匹配,显示匹配的节点即可。

            getAllPath(node, path = []) {
              if (!node) {
                return null; // 如果为空节点则返回null
              }

              const currentVal = node.value; // 当前节点值
              path.push(currentVal); // 将当前节点值添加到路径数组中

              if (!node.children || node.children.length === 0) {
                // console.log('路径:', path); // 输出完整路径
                this.myResult.push(path);
              } else {
                for (let i = 0; i < node.children.length; i++) {
                  this.getAllPath(node.children[i], [...path]); // 对每个子节点进行递归调用
                }
              }

              // path.pop(); // 移除最后一个元素,因为已经处理过该节点了
            },
  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
element-ui 中的 Cascader 级联选择器需要一个级联的数据源,这个数据源可以是一个普通的数组或者是一个包含子节点的树形结构。如果数据源是一个普通的数组,需要通过递归处理将其转化为树形结构。 以下是一个示例代码,将普通的数组转化为树形结构: ```js function convertToTree(data) { let result = [] let map = {} // 先将所有数据按照 id 存入一个 map 中 for (let i = 0; i < data.length; i++) { map[data[i].id] = data[i] } // 将所有数据遍历一遍,如果当前数据有 parentId,将其作为父节点的子节点存入父节点的 children 中 for (let i = 0; i < data.length; i++) { let item = data[i] if (item.parentId) { let parent = map[item.parentId] if (parent) { if (!parent.children) { parent.children = [] } parent.children.push(item) } } else { result.push(item) } } return result } ``` 在上述代码中,首先将所有数据按照 id 存入一个 map 中,然后遍历所有数据,如果当前数据有 parentId,就将其作为父节点的子节点存入父节点的 children 中,最后返回处理后的树形结构。 使用示例: ```js let data = [ { id: 1, name: '选项1' }, { id: 2, parentId: 1, name: '选项1-1' }, { id: 3, parentId: 1, name: '选项1-2' }, { id: 4, name: '选项2' }, { id: 5, parentId: 4, name: '选项2-1' }, { id: 6, parentId: 4, name: '选项2-2' } ] let treeData = convertToTree(data) console.log(treeData) ``` 输出结果: ```js [ { "id": 1, "name": "选项1", "children": [ { "id": 2, "parentId": 1, "name": "选项1-1" }, { "id": 3, "parentId": 1, "name": "选项1-2" } ] }, { "id": 4, "name": "选项2", "children": [ { "id": 5, "parentId": 4, "name": "选项2-1" }, { "id": 6, "parentId": 4, "name": "选项2-2" } ] } ] ``` 将转换后的数据源作为 Cascader 的 options 属性即可完成级联选择器的数据递归处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值