在vue 官方看到写的tree结构是组件自调用产生递归生成树形结构,然后我测试了一下将它利用在菜单上面了
parent组件
<template>
<ul>
<li id="demo" v-for="first in treeData">
<tree-item class="item" :item="first" />
</li>
</ul>
</template>
<script>
import treeItem from "./treeItem";
const menu = [
{ id: 1, name: "首页", pid: 0, icon: 'el-icon-s-home' },
{ id: 2, name: "内容创作", pid: 0, icon: 'el-icon-edit-outline' },
{ id: 21, name: "发表博文", pid: 2, icon: 'el-icon-document' },
{ id: 221, name: "新闻", pid: 21, icon: 'el-icon-star-off' },
{ id: 22, name: "上传资源", pid: 2, icon: 'el-icon-document' },
{ id: 23, name: "上传视频", pid: 2, icon: 'el-icon-document' },
{ id: 23, name: "发布问题", pid: 2, icon: 'el-icon-document' },
{ id: 3, name: "内容管理", pid: 0, icon: 'el-icon-document' },
{ id: 31, name: "文章管理", pid: 3, icon: 'el-icon-document' },
{ id: 32, name: "资源管理", pid: 3, icon: 'el-icon-document' },
{ id: 33, name: "评论管理", pid: 3, icon: 'el-icon-document' },
{ id: 34, name: "分类专栏", pid: 3, icon: 'el-icon-document' },
{ id: 35, name: "视频管理", pid: 3, icon: 'el-icon-document' },
{ id: 36, name: "自定义模块", pid: 3, icon: 'el-icon-document' },
{ id: 37, name: "订阅专栏", pid: 3, icon: 'el-icon-document' },
{ id: 38, name: "问答管理", pid: 3, icon: 'el-icon-document' },
{ id: 4, name: "数据观星", pid: 0, icon: 'el-icon-pie-chart' },
{ id: 41, name: "博文数据", pid: 4, icon: 'el-icon-document' },
{ id: 42, name: "下载数据", pid: 4, icon: 'el-icon-document' },
{ id: 43, name: "收益数据", pid: 4, icon: 'el-icon-document' },
{ id: 44, name: "粉丝数据", pid: 4, icon: 'el-icon-document' },
{ id: 45, name: "粉丝数据", pid: 4, icon: 'el-icon-document' },
{ id: 46, name: "一周小结", pid: 4, icon: 'el-icon-document' },
{ id: 5, name: "收益中心", pid: 0, icon: 'el-icon-coin' },
{ id: 6, name: "创作活动", pid: 0, icon: 'el-icon-ship' },
{ id: 61, name: "活动列表", pid: 6, icon: 'el-icon-document' },
{ id: 62, name: "投稿管理", pid: 6, icon: 'el-icon-document' },
{ id: 7, name: "工具", pid: 0, icon: 'el-icon-setting' },
{ id: 71, name: "搬家", pid: 7, icon: 'el-icon-document' },
{ id: 72, name: "博客打赏", pid: 7, icon: 'el-icon-document' },
{ id: 73, name: "开头付费资源", pid: 7, icon: 'el-icon-document' },
{ id: 8, name: "创作权益", pid: 0, icon: 'el-icon-trophy' },
{ id: 81, name: "等级权益", pid: 8, icon: 'el-icon-document' },
{ id: 82, name: "自定义域名", pid: 8, icon: 'el-icon-document' },
{ id: 9, name: "设置", pid: 0, icon: 'el-icon-s-tools' },
{ id: 91, name: "博客设置", pid: 9, icon: 'el-icon-document' },
];
export default {
name: "tree",
components: { treeItem },
data() {
return {
treeData: []
};
},
mounted() {
this.treeData = this.__toTree(menu);
},
methods: {
__toTree(data) {
data.forEach(item => delete item.children);
let map = {}, val = [];
data.forEach(item => (map[item.id] = item));
data.forEach((item, index) => {
let parent = map[item.pid];
if (parent) (parent.children || (parent.children = [])).push(item);
else val.push(item);
});
return val;
}
}
};
</script>
<style lang='stylus' scoped>
ul {
padding-left: 1em;
line-height: 1.5em;
width: 200px;
background-color: #409EFF;
color: #fff;
}
</style>
children 组件
<template >
<div :class="{'second-level': second, 'third-level': third}">
<p @click="toggle">
<b :class="item.icon"></b>
{{ item.name }}
<i v-if="isFolder" :class="icon"></i>
</p>
<ul v-show="isOpen" v-if="isFolder">
<tree-item class="item" v-for="(child, index) in item.children" :key="index" :item="child" />
</ul>
</div>
</template>
<script>
export default {
name: "treeItem",
data() {
return {
isOpen: false
};
},
props: ["item"],
methods: {
toggle() {
if (this.isFolder) this.isOpen = !this.isOpen;
}
},
computed: {
isFolder() {
return this.item.children && this.item.children.length;
},
icon() {
return this.isOpen ? "el-icon-arrow-down" : "el-icon-arrow-right";
},
second() {
return this.item.children && this.item.pid > 0;
},
third() {
return !this.item.children && this.item.pid > 0;
}
}
};
</script>
<style lang='css' scoped>
p {
position: relative;
}
b {
margin-right: 5px;
}
i {
position: absolute;
top: 2.5px;
right: 20px;
}
.second-level, .third-level {
margin-left: 10px;
}
</style>
</style>