最近遇见一个需求,生成目录树,奈何只有第一层数据是固定的,所有的子目录都要通过懒加载的方式获取,点击按钮的时候调取接口获取下级目录,故此写个demo记录下,下次懒得再看一遍文档了
懒加载功能事件主要是通过 :load=“loadNode” 方法实现的
第二个主要方法 :props=“props” 是用作数据映射
映射的是当前目录树绑定的数组键值名称,例如:
官方使用的绑定数据是:
[{
id: 1,
label: '一级 1',
children:[]
}]
我们本地的数据是:
[{
"id": "1001",
"type": null,
"nodeName": "指标",
"next":[{
"id": "1001"
}]
}]
这个时候
- nodeName 对应为 label
- next 对应为 children
故此可以用 :props=“props”
props的值为:
data() {
return {
data: [],
props: {
children: 'next',
label: 'nodeName'
},
}
},
现在直接放代码,一些相关事件记录在代码下面:
lazyTree.vue 页面
注意: 当前树是写成子组件的方式,在父组件中引入使用的
<template>
<div class="tree_wrap">
<!-- 指标树 -->
<el-tree
ref="tree"
:props="defaultProps"
@node-expand="handlerOpen"
node-key="id"
:default-expanded-keys="titleIndex"
@node-click="handleNodeClick"
:highlight-current="showTree"
lazy
:load="loadNode"
>
<span class="custom-tree-node" slot-scope="{ data }">
<span>
<i :class="data.icon" v-if="data.icon" style="font-size:16px;"></i>
{{ data.nodeName }}
</span>
</span>
</el-tree>
</div>
</template>
<script>
// 这个是获取子目录的接口
import { searchChildern} from '@/network/daptDataUrl'
// 第一层假数据 第一层数据值为固定值 无需懒加载
import treeData from './tree.json'
export default {
props:{
// 默认展开的分类id
titleIndex: {
type: Array,
default: []
}
},
data() {
return {
// 数据映射
defaultProps: {
children: 'next',
label: 'nodeName'
},
cheackId:'', // 当前选中的目录id
showTree:true, // 是否高亮当前选中节点
childerList:[],// 子目录
}
},
created(){
console.log('父组件传过来的节点:',this.titleIndex)
// titleIndex 是默认展开目录的 id集合数组
// cheackId 是代表当前选中的目录id
this.cheackId = this.titleIndex[0]
},
mounted(){
this.getCurrentKey()
},
methods: {
handlerOpen(data) {
// console.log("展开操作",data);
this.cheackId = data.id
},
//跳转当前页面后 设置默认展开和选中的目录
getCurrentKey(){
let key = ''
if(this.titleIndex.length == 1){
key = this.titleIndex[0];
}else{
key = this.titleIndex[1];
}
console.log('key:',key)
this.$nextTick(function(){
//通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性
this.$refs.tree.setCurrentKey(key);
})
this.cheackId = this.titleIndex[0]
},
// 点击节点事件
handleNodeClick(data, node) {//指标
this.$nextTick(()=>{
// 若为 null 则取消当前高亮的节点
this.$refs.tree.setCurrentKey(null)
})
this.getResouce(data,node)
},
// tree组件向父组件通讯
getResouce(data,node){
try {
console.log("点击事件",'data:',data,"node",node);
this.cheackId = data.id
// 这个事件是传递给父组件 告诉父组件点击了当前目录 可以在父组件做其他的数据操作
this.$emit('get-detail',data)
} catch (error) {
console.log("await函数报错!");
}
},
// 懒加载下级数据
loadNode(node, resolve) {
// console.log("懒加载子目录",node,treeData);
// 层级为零时 返回写死的父目录 也可以都通过接口请求
if (node.level === 0) {
// console.log("node.level",node.level);
// treeData 是json文件中的数据 放在下面
return resolve(treeData.firstLever);
}
// 层级为一时 返回写死的二级目录
if (node.level === 1) {
// console.log("node.level",node.level,treeData);
return resolve(treeData.targetsecondLever);
}
//当层级大于1时 使用接口获取子目录 使用resolve回调函数返回子目录数据
if (node.level > 1) {
this.getNextNode(node.data,resolve)
}
// return resolve([]);
},
getNextNode(nodeData,resolve){
// 这里是子级目录的 接口请求操作
let params = {
type:"",//类型
parentNodeCode: "",//父级节点编码
}
console.log("请求子节点入参",nodeData,params);
searchChildern(params).then((response)=>{
console.log("子节点数组",response.data);
let res = response.data
if (res.status == 1) {
this.childerList = res.data
resolve(res.data)
} else {
console.log("子节点获取失败!!");
this.childerList = []
}
}).catch((err)=>{
console.log("子节点获取失败!!");
})
}
}
}
</script>
tree.json 假数据
{
"firstLever":[
{
"id": "1001",
"type": null,
"nodeName": "指标",
"next":[{
"id": "1001"
}]
}
],
"targetsecondLever":[{
"id": "-1",
"type": "1",
"nodeName": "公司体系",
"next": [{}]
}, {
"id": "-2",
"type": "2",
"nodeName": "外部体系",
"next": [{}]
}, {
"id": "-3",
"type": "3",
"nodeName": "专题体系",
"next": [{}]
},
{
"id": "-4",
"type": "4",
"nodeName": "台区体系",
"next": [{}]
}
]
}
父组件调用 Index.vue 页面
<template>
<div class="treeSwich">
<LazySidebar :titleIndex="titleIndex" @get-detail="clickAside"></LazySidebar>
</div>
</template>
<script>
import LazySidebar from './lazyTree.vue';
export default {
data() {
return {}
},
methods: {
// 点击侧边栏 请求资源
clickAside(data){
console.log('侧边栏数据:', data)
}
}
}
</script>
相关事件:
-
节点被展开时触发的事件:
@node-expand="handlerOpen"
-
默认勾选的节点的 key 的数组 titleIndex是个数组
:default-expanded-keys=“titleIndex” -
节点被点击时的回调
@node-click=“handleNodeClick”
节点被点击之后要先清除上一次高亮的目录节点,然后再调取获取子目录数据的接口 -
点击子组件后 父组件需要进行的相关操作,通过父子组件通讯实现
this.getResouce() 函数中this,$emit()事件通知了父组件节点已经被点击,可以请求相关数据了
tip:
如果目录树需要展示相关图表,可以在绑定数据中新增icon字段,放置相关icon值,即可渲染
实例数据:
"firstLever":[
{
"id": "1001",
"type": null,
"nodeName": "指标",
"icon": "el-icon-s-tools",
"next":[{
"id": "10010"
}]
}
],
哦了 总结完毕~~~