1. 项目中的功能需求
一次性获取所有的设备数据,形成树结构,做增删改查时调用接口后直接更新本地数据,保持跟后端数据同步,做快速响应(毕竟每次操作都拿十万数据重新结构化台耗费时间了)
2. 该功能中应用到的知识点和组件
1. js Worker 多线程
2. 递归算法结构化数据并过滤需要的数据
3. el-tree懒加载模式(直接加载全部数据根本加载不出来)
4. el-cascader懒加载模式(树结构级联选择组件)
3. 具体实现步骤
1. 调用接口获取数据,平台做加载弹窗提示数据封装
2. 获取数据后使用new Worker(url)启动线程把数据传进线程处理结构化数据,定义全局参数
// 开启Worker线程
globalVariable.worker = new Worker("worker.js");
// 2.主线程监听函数接收消息
globalVariable.worker.onmessage = e => {
// 线程处理完的数据使用全局参数接收
globalVariable.deviceList = e.data.deviceList;
globalVariable.deviceObj = e.data.deviceObj;
};
// 1.主线程向子线程发送消息
globalVariable.worker.postMessage(接口请求到的数据);
// worker.js 内容
self.addEventListener("message", e => {
// 处理数据逻辑,简单改成树结构
let res = e.data;
let deviceObj = {};
res.forEach((item, index) => {
deviceObj[item.id] = item;
});
res.forEach((item, index) => {
if(deviceObj[item.parentId]){
if (deviceObj[item.parentId].children) {
deviceObj[item.parentId].children.push(i);
} else {
deviceObj[item.parentId].children = [item];
}
}
});
self.postMessage({deviceObj, deviceList: res});
})
3. 拿一二级数据传入(注意传进去时二级数据的children要删除),点击二级数据时查出该数据字节点数组,使用updateKeyChildren插入。
<div
:style="{ paddingRight: scroll + 'px' }"
v-loading="treeLoading"
>
<el-tree
:ref="elTree"
:data="data"
node-key="id"
:default-expanded-keys="expandedKeys"
:props="{ children: "children", label: "label" }"
@node-click="handleNodeClick"
>
</el-tree>
</div>
<script>
export default {
data(){
return {
data: [],
expandedKeys: []
}
},
created(){
// 顶级节点id设置为0
let data = globalVariable.deviceObj["0"];
data.children.map(item => {
let obj = { ...item };
delete obj.children;
return obj;
});
// 先加载2级节点
this.data = data;
}
methods:{
handleNodeClick(val){
let children = globalVariable.deviceObj[val.id].children.map(item => {
return {
...item,
children: null
}
});
this.$refs.elTree.updateKeyChildren(val.id, children);
// 展开节点
setTimeout(() => {
this.expandedKeys = [val.DeviceId];
}, 10);
}
}
}
</script>