1.模拟数据
data() {
return {
treeList: [
{ id: 1, name: "1", pid: 0 },
{ id: 2, name: "1-1", pid: 1 },
{ id: 3, name: "1-2", pid: 1 },
{ id: 4, name: "1-1-1", pid: 2 },
{ id: 5, name: "2", pid: 0 },
],
flag: true,
};
},
getMenu(){
let getList = new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 3000);
});
getList
.then(() => {
//模拟接口获取数据
let list = this.flag ? this.treeList : [];
//找出对应的一级 id
const parent = list.filter((item) => item.pid === 0);
//遍历所有一级的项
for (const i of parent) {
//调用 递归函数 传入当前的一级 && 所有的数据
this.getTree(i, list);
}
this.arr = parent;
console.log(1);
})
.catch(() => {
console.log("失败");
});
}
2.递归
getTree(parent, list) {
// 在所有的数据中找有没有和当前一级项对应的 id
const children = list.filter((item) => item.pid === parent.id);
// 有 length 说明找到了,有子级
if (children.length) {
// 再接着找子级的每一项有没有下级
for (const child of children) {
this.getTree(child, list);
}
// 最后!!! 给上级添加 children
parent.children = children;
}
},
3.渲染
因为不知道有几级,少的话还好说,如果几十上百条,所以用到递归组件
1.创建组件
2.接收数据
<script>
export default {
name: "TreeMenu",
props: {
arr: {
type: Array,
},
},
};
3.template
<template>
<div>
<div v-for="(item, index) in arr" :key="index">
<div>{{ item.name }}</div>
// 递归自身,此时 arr 是 item.children
<tree-menu :arr="item.children">
// 必须有结束条件,不然会报错
<div v-for="(it, idx) in arr" :key="idx" v-if="it.id">{{ it.name }}</div>
</tree-menu>
</div>
</div>
</template>
必须有结束条件,不然会报错( 之前试的报错,现在想放一个报错的截图,结果不报错了,有知道原因的大神求帮助 )
4.样式
<style lang="scss" scoped>
div {
padding-left: 20px;
}
</style>