这两天组长给我一个需求,调取接口,返回的是一个嵌套的对象数组,要求做成树形结构
类似这种,给的设计图的checkbox是在右边.
我当时没想到修改样式的方法,就使用插槽自己写了个checkbox.
由此产生一系列问题,花费时间较多,所以记录一下.
后端的这个接口传回来的数据是全部名单,全部名单数据中,没有checked这个属性,通过递归进行添加checked属性.
然后怎么跟插槽内自己写的checkbox绑定呢.
查看elementui官方文档,发现有个node,node可以获得树节点.
通过函数打印node,发现node里面有个data属性,data属性就是当前节点绑定的数据.
就可以实现checkbox的勾选
前文提到node.data是当前节点绑定的数据.
打印node.data,可以看到父节点中有个children属性.children属性中就是所有子节点的data
但是这个只是静态的,无法在勾选的时候判断.el-checkbox中有个change方法,在更改勾选状态的时候执行的函数.
所以在checkbox中添加事件@change(node),将当前节点当做参数传入函数.
在函数中,先通过node.data.children判断是不是父节点.
如果是父节点,就要在点击的时候,更改所有子节点的checked.再判断node.data.checked,如果为真,通过forEach将所有子节点的checked改为true;反之同理
如果是子节点,就要点击的时候提取node.data.id,通过原始数据找到这个子节点.再通过这个子节点的父节点的children属性,用every方法返回一个布尔值.这个布尔值就是父节点的checked的属性值
这一点我是通过计算属性实现的.计算属性可以传参,但是不能直接传参.可以通过
computed:{
indeterminate(){
return function(node){ //计算属性不能直接传参,所有通过返回一个函数的方法进行传参
if(node.children){ // 首先判断是不是父节点
if(!node.checked){ // 如果是父节点 并且没有勾选
const a = node.children.every(item => item.checked === true) // 所有的子节点都勾选会返回 true
const b = node.children.some(item1 => item1.checked === true) // 所有的子节点只要有一个勾选就返回true
if(!a&&b){ // 如果子节点没有都勾选,但是最少有一个勾选 就返回true
return true
}
}
}
}
}
}
在el-checkbox属性中添加 :indeterminate="indeterminate(node)"
就可以动态勾选状态了.