element中el-tree动态(懒)加载节点与自定义过滤
项目(vue+TS)背景,总共有三级菜单,二级菜单数据是已有的,三级菜单数据是根据二级菜单动态拉取渲染的,且当第二次请求时,不在重新请求,只是把上一次请求的数据拿来渲染就行了,减少了请求。参考 element-UI-tree按需引入element.jsimport {Scrollbar,} from "element-ui";Vue.use(Scrollbar);...
·
项目(vue+TS)背景,总共有三级菜单,二级菜单数据是已有的,三级菜单数据是根据二级菜单动态拉取渲染的,且当第二次请求时,不在重新请求,只是把上一次请求的数据拿来渲染就行了,减少了请求。
按需引入
element.js
import {
Scrollbar,
} from "element-ui";
Vue.use(Scrollbar);
template
<el-scrollbar wrap-class="scroll-viewport-tree">
<div class="container">
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
:load="loadNode"
lazy
></el-tree>
</div>
</el-scrollbar>
相关数据
private treeData: arrayData = [];
private defaultProps = {
children: "children",
label: "label",
isLeaf: "leaf"
};
由本地数据生成一级节点树
private generateTreeData(): void {
this.treeData = [];
const firstChild: any = [];
for (const k in this.ROLE_TYPE) {
firstChild.push({
label: this.ROLE_TYPE[k],
key: k,
children: []
});
}
this.treeData = [
{
label: this.UserInfo.project_name,
children: [...firstChild]
}
];
}
这里设置懒加载事件
private async loadNode(node: objectData, resolve: Function): any {
//一级默认显示
if (node.level === 0) {
return resolve(this.treeData);
}
//二级直接放回本地数据
if (node.level === 1) {
setTimeout(() => {
return resolve(this.treeData[0].children);
});
}
// 点击二级菜单时候异步拉取数据做渲染
if (node.level === 2) {
if (node.data.key) {
try {
let data!: arrayData;
if (
this.treeData[0].children[node.data.key - 1].children.length > 1
) {
data = this.treeData[0].children[node.data.key - 1].children;
} else data = await this.getAdminsByRole(node.data.key);
return resolve(data);
} catch (err) {
// 捕获promise错误
this.$message.error(err.toString());
}
}
}
if (node.level > 2) {
return resolve([]);
}
}
获取数据函数
private getAdminsByRole(key: string): any {
const key1 = Number(key);
return new Promise((resolve, reject) => {
this.$https.userMan
.getAllAdmin({
data: {
role: 2
}
})
.then((res: fetchResponse) => {
if (res.flag === 1 && res.data.results.length > 0) {
res.data.results.forEach((item: objectData) => {
this.treeData[0].children[key1 - 1].children.push({
label: item.nickname,
// leaf为true时,展开节点没有下拉符号(三角)
leaf: true,
children: [],
...item
});
});
this.treeData[0].children[key1 - 1].children.shift();
resolve(this.treeData[0].children[key1 - 1].children);
} else reject();
})
.catch((err: any) => reject(err));
});
}
最后效果:
自定义过滤:
页面样子
如果使用官方过滤:
this.refs.tree.filter(params)
eslint会报错:
当然不影响执行,但是这种错误会导致打包失败,当然各位看官如果有办法解决此error,欢迎留言
想要避免错误参考: vue+ts对element $refs.xxx.methods的支持
最后的搜索方法,其实就是利用nickname和id筛选子节点
private search() {
const { nickname, id } = this.searchInfo;
//this.$refs.tree.filter([nickname, id])
this.treeData = deepClone(this.treeDataSource);
this.treeData[0].children.forEach((item: objectData) => {
// 过滤后的子节点
const subArr: arrayData = [];
item.children.forEach((val: objectData) => {
if (
val.nickname.indexOf(nickname) !== -1 &&
String(val.id).indexOf(id) !== -1
) {
subArr.push(val);
}
});
item.children = [...subArr];
});
this.treeData[0].children = this.treeData[0].children.filter(item => {
return item.children.length > 0;
});
if (this.treeData[0].children.length === 0) {
this.errorTips = "查询该用户失败!";
} else {
// 奇怪的是这个默认展开无效
this.expandTree = true;
this.errorTips = "";
}
}
更多推荐
已为社区贡献11条内容
所有评论(0)