前端解析无限下钻级联部门数据,并绑定到el-cascader级联下拉框组件中

需求背景:

项目web端系统中有一处功能,需要通过http post请求后端提供的API接口,传入登录用户所属部门id参数,动态获取未知级数的级联部门数据的,再进行前端解析,构造成能装入el-cascader级联选择框组件中的数据结构?

继上文: mysql分级无限下钻递归查询sql
已实现无限级联部门数据的查询sql,可以编写通过用户所属部门id查询动态级联部门数据的API。

1. 后端API返回的数据结构

前端通过http请求该接口,返回的数据结构如下:

const data = [
    {
        "id": 1,
        "name": "司令",
        "parentId": 0
    },
    {
        "id": 2,
        "name": "军长",
        "parentId": 1
    },
    {
        "id": 3,
        "name": "师长A",
        "parentId": 2
    },
    {
        "id": 4,
        "name": "师长A",
        "parentId": 2
    },
    {
        "id": 5,
        "name": "旅长",
        "parentId": 3
    },
    {
        "id": 6,
        "name": "团长",
        "parentId": 5
    },
    {
        "id": 7,
        "name": "营长A",
        "parentId": 6
    },
    {
        "id": 8,
        "name": "营长B",
        "parentId": 6
    },
    {
        "id": 9,
        "name": "连长A",
        "parentId": 7
    },
    {
        "id": 10,
        "name": "连长B",
        "parentId": 8
    },
    {
        "id": 11,
        "name": "连长C",
        "parentId": 8
    },
    {
        "id": 12,
        "name": "排长A",
        "parentId": 9
    },
    {
        "id": 13,
        "name": "排长B",
        "parentId": 11
    }   
]

2. 前端解析构造el-cascader组件适配的数据结构

返回的数据属于一维数组结构,但是此结构的数据无法直接填入ElementUI的Cascader级联选择器组件中,因此需要在前端实现数据的重新构造,构造方法如下:

// 构造任意级数的部门级联数据
const transformTree = function(list, userDepartmentId){
  let newArr=[]
  list.filter(v=>v.id==userDepartmentId).forEach(d=>{
    let item = queryChildren(d, list)
    item.label = d.name
    item.value = d.id
    newArr.push(item)
  })
  return newArr;
}

// 递归构造子级(children)数据
const queryChildren = function(parent, list){
  let new_parent = []
  new_parent.label = parent.name
  new_parent.value = parent.id
  let children = []
  list.filter(v=>v.parentId == parent.id).forEach(v=>{
    let item1 = queryChildren(v, list)
    item1.label = v.name
    item1.value = v.id
    children.push(item1)
  })
  if(children.length){
    new_parent.children = children;
  }
  return new_parent;
}



let userDepartmentId = 5
// data是请求返回的部门数据
// userDepartmentId是登录用户所属部门id(因为不同的登录用户看到的级联组件中的数据是不一样的,无法看到或操作其父级部门的数据)
let new_data = transformTree(data, userDepartmentId)
console.log(new_data);

构造后的数据结构如下:
在这里插入图片描述
如果有多个层级的子级,则以嵌套children数组的形式呈现。

3. 页面效果呈现

将解析后的数据直接绑定到el-cascader组件中,这里已传入userDepartmentId = 5为例:
在这里插入图片描述

4. 完整样例代码

可以将代码拷贝到 ElementUI提供的在线运行平台上测试效果:https://codepen.io/pen

HTML
<script src="//unpkg.com/vue@2/dist/vue.js"></script>
<script src="//unpkg.com/element-ui@2.15.10/lib/index.js"></script>
<div id="app">
<div class="block">
  <span class="demonstration">单选可搜索</span>
  <el-cascader
    placeholder="试试搜索:指南"
    :options="options"
    filterable></el-cascader>
</div>
</div>
CSS
@import url("//unpkg.com/element-ui@2.15.10/lib/theme-chalk/index.css");
JS
var Main = {
    data() {
      return {
        options: []
      };
    },
    mounted(){
      const data = [
        {
            "id": 1,
            "name": "司令",
            "parentId": 0
        },
        {
            "id": 2,
            "name": "军长",
            "parentId": 1
        },
        {
            "id": 3,
            "name": "师长A",
            "parentId": 2
        },
        {
            "id": 4,
            "name": "师长A",
            "parentId": 2
        },
        {
            "id": 5,
            "name": "旅长",
            "parentId": 3
        },
        {
            "id": 6,
            "name": "团长",
            "parentId": 5
        },
        {
            "id": 7,
            "name": "营长A",
            "parentId": 6
        },
        {
            "id": 8,
            "name": "营长B",
            "parentId": 6
        },
        {
            "id": 9,
            "name": "连长A",
            "parentId": 7
        },
        {
            "id": 10,
            "name": "连长B",
            "parentId": 8
        },
        {
            "id": 11,
            "name": "连长C",
            "parentId": 8
        },
        {
            "id": 12,
            "name": "排长A",
            "parentId": 9
        },
        {
            "id": 13,
            "name": "排长B",
            "parentId": 11
        } 
       ];
      this.options = this.transformTree(data, 5)
      console.log(this.options)
    },
    methods:{
      // 构造任意级数的部门级联数据
      transformTree:function(list, userDepartmentId){
        let newArr=[]
        list.filter(v=>v.id==userDepartmentId).forEach(d=>{
          let item = this.queryChildren(d, list)
          item.label = d.name
          item.value = d.id
          newArr.push(item)
        })
        return newArr;
      },
      // 递归构造子级(children)数据
      queryChildren:function(parent, list){
        let new_parent = []
        new_parent.label = parent.name
        new_parent.value = parent.id
        let children = []
        list.filter(v=>v.parentId == parent.id).forEach(v=>{
          let item1 = this.queryChildren(v, list)
          item1.label = v.name
          item1.value = v.id
          children.push(item1)
        })
        if(children.length){
          new_parent.children = children;
        }
        return new_parent;
      }
    }
  };
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')

5. 级联下拉框选择后的数据获取

注意:级联下拉框组件在选择后,获取数据需要注意

// 如果departmentId1的值是通过部门级联下拉菜单选出的(数组)对象,则取(数组)对象最后一个元素作为departmentId1的值
if (departmentId1 instanceof Object) {
  let departmentIdArr = Array.prototype.slice.call(departmentId1);
  // 收起下拉菜单
  if (departmentIdArr.length > 0) {
    this.$refs.cascader1.dropDownVisible = false;
  }
  departmentId1 = departmentIdArr[departmentIdArr.length - 1];
}

6. 参考链接

Js 如何把数据变成级联结构数据 - 作者:甘道夫老矣

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kyrielx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值