1. 需求分析
将多个一级目录存放在el-select多选框,选定该目录,则在el-tree中展示中该一级目录下的所有子集选项,通过多选框过滤el-tree的数据,大致效果图如下所示:
2. 代码分析
首先展示数据解构:
//数据
data: [
{
id: 1,
label: '理论课',
children: [
{
id: 4,
label: '中心论点',
children: [
{
id: 9,
label: '突出论点',
},
{
id: 10,
label: '突出分论据',
},
],
},
],
},
{
id: 2,
label: '体育课',
children: [
{
id: 5,
label: '教学质量',
},
{
id: 6,
label: '学生意见',
},
],
},
{
id: 3,
label: '英语课',
children: [
{
id: 7,
label: '阅读理解',
},
{
id: 8,
label: '写作',
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
//绑定了el-select,选定相应id时展示该id下的数据
showData: null,
//存放评价项和所有子集的数组
arr:null,
//更换课程时的中间值
courseFlag:null,
这里最棘手的是,子集下又有多少个子集的存在,这里就需要算法来实现。
el-select多选框,即遍历展示一级目录如下所示:
<el-select v-model="showData" placeholder="请选择">
<el-option
v-for="item in data"
:key="item.id"
:label="item.label"
:value = "item.id"
>
</el-option>
</el-select>
el-tree代码如下所示
<el-tree
:props="defaultProps"
:data="data"
node-key="id"
default-expand-all
ref="treeForm"
check-strictly
show-checkbox
//多选框实现单选效果
@check-change="handleNodeClick"
//过滤el-tree树
:filter-node-method="filterNode"
>
</el-tree>
过滤el-tree树代码如下所示:
这里过滤树节点的大致思路,将选定的一级目录下的所有children都转换为一个数组,方便indexOf遍历判断该数据是否存在于数组中。
methods:{
//过滤树节点
filterNode(value, data) {
if(data.id===value){
//这里使用了递归,this.arr将一级目录下的children,以及children下的children...
//确保了无论有多少个children,最终都平行存放在该数组中
this.arr = this.arrOfOneDimension(data.children)
return true
}else {
if(this.arr!=null && this.arr.length>0){
if(this.arr.indexOf(data)!==-1){
//判断后就删除该元素,是为了下一次点击不会造成数据泄露!
this.arr.splice(this.arr.indexOf(data),1);
return true;
}else{
//还原数组
this.arr = null;
return false;
}
}
return false
}
},
}
watch: {
//监控showData的变化
showData(newValue) {
this.$refs.treeForm.filter(newValue);
//用介质值存储变化的值,确保当在改节点点击新增后,整个el-tree树结构不会重构,依旧是el-select选定的值
this.courseFlag = newValue
},
},
mounted() {
//初始化时,未选定多选框,过滤所有目录
this.$refs.treeForm.filter(null);
},
updated(){
//树结构变化时确保tree节点不会重构
this.$refs.treeForm.filter(this.courseFlag);
}
递归算法代码如下所示:
methods:{
//递归抽取data中子集对象和子集的子集
arrOfOneDimension(arr){
for (let key of arr) {
if (Array.isArray(key.children)) {
newArr.push(key);
//如果还是数组继续递归调用,传入该子集的子集,知道该子集下再无子集!
this.arrOfOneDimension(key.children);
} else {
newArr.push(key);
}
}
return newArr;
},
}
3.后言
该文记录了自己在前端开发中,遇上的“怪需求”,初次遇见时,差点想放弃,最终还是秉承“没有实现不了的需求”的原则,最终程序还是如愿以偿的跑起来了。