下面是详细讲解“vuejs实现递归树型菜单组件”的完整攻略:
1. 什么是递归树型菜单?
递归树型菜单是一种树形结构的组件,其中每个节点都可以有零个或多个子节点,即包含自身,并且可以无限扩展嵌套,这种组件在电商、SaaS、掌上运维等类型的系统中都比较常见。
2. 实现递归树型菜单组件的过程
步骤一:创建组件
首先,我们需要创建一个“TreeNode”组件,该组件负责渲染每一个树形菜单节点和子节点。
<template>
<div class="tree-node">
<!-- 菜单节点 -->
<div class="node-item" :class="{'active': node.id === activeNodeId}" @click="handleClick">
{{ node.title }}
</div>
<!-- 子节点列表 -->
<div v-if="node.children.length" class="children-list">
<Tree-Node v-for="child in node.children" :key="child.id" :node="child" :activeNodeId="activeNodeId" @click="handleChildClick" />
</div>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: {
node: {
type: Object,
default: () => ({})
},
activeNodeId: Number
},
methods: {
handleClick() {
this.$emit('click', this.node)
},
handleChildClick(node) {
this.$emit('click', node)
}
}
}
</script>
<style lang="scss">
.tree-node {
.node-item {
padding: 5px 10px;
cursor: pointer;
&:hover {
background-color: #f5f5f5;
}
&.active {
background-color: #1890ff;
color: #fff;
}
}
.children-list {
margin-left: 20px;
}
}
</style>
步骤二:递归渲染菜单树
在“App”组件中,我们加载菜单树数据并渲染菜单树,需要用到递归的方式。因为一个菜单项可能包含子菜单项,每个子菜单项也可能包含子菜单项,所以我们需要使用递归的方式去渲染菜单树。
<template>
<div class="app">
<Tree-Node v-for="item in treeData" :key="item.id" :node="item" :activeNodeId="activeNodeId" @click="handleNodeClick" />
</div>
</template>
<script>
import TreeNode from './components/TreeNode.vue'
export default {
name: 'App',
components: { TreeNode },
data() {
return {
activeNodeId: 1,
treeData: [
{
id: 1,
title: '一级菜单1',
children: [
{
id: 2,
title: '二级菜单1',
children: [
{
id: 3,
title: '三级菜单1',
children: []
}
]
},
{
id: 4,
title: '二级菜单2',
children: []
}
]
},
{
id: 5,
title: '一级菜单2',
children: []
}
]
}
},
methods: {
handleNodeClick(node) {
this.activeNodeId = node.id
}
}
}
</script>
<style lang="scss">
.app {
padding: 20px;
background-color: #f5f5f5;
}
</style>
以上就是实现递归树型菜单组件的过程,通过以上方法,我们可以轻松地创建递归树型菜单组件,如下面两个示例:
示例一:简单的递归树型菜单(无异步加载)
<template>
<div class="app">
<Tree-Node v-for="item in treeData" :key="item.id" :node="item" :activeNodeId="activeNodeId" @click="handleNodeClick" />
</div>
</template>
<script>
import TreeNode from './components/TreeNode.vue'
export default {
name: 'App',
components: { TreeNode },
data() {
return {
activeNodeId: 1,
treeData: [
{
id: 1,
title: '一级菜单1',
children: [
{
id: 2,
title: '二级菜单1',
children: [
{
id: 3,
title: '三级菜单1',
children: []
}
]
},
{
id: 4,
title: '二级菜单2',
children: []
}
]
},
{
id: 5,
title: '一级菜单2',
children: []
}
]
}
},
methods: {
handleNodeClick(node) {
this.activeNodeId = node.id
}
}
}
</script>
<style lang="scss">
.app {
padding: 20px;
background-color: #f5f5f5;
}
</style>
示例二:带异步加载的递归树型菜单
<template>
<div class="app">
<button @click="handleLoadData">加载数据</button>
<Tree-Node :node="treeData" :activeNodeId="activeNodeId" @click="handleNodeClick" />
</div>
</template>
<script>
import TreeNode from './components/TreeNode.vue'
export default {
name: 'App',
components: { TreeNode },
data() {
return {
activeNodeId: 1,
treeData: {
id: 1,
title: '根节点',
children: []
}
}
},
methods: {
handleNodeClick(node) {
this.activeNodeId = node.id
},
handleLoadData() {
// 模拟异步获取数据
setTimeout(() => {
this.treeData.children = [
{
id: 2,
title: '一级菜单1',
children: []
},
{
id: 3,
title: '一级菜单2',
children: [
{
id: 4,
title: '二级菜单1',
children: []
}
]
}
]
}, 1000)
}
}
}
</script>
<style lang="scss">
.app {
padding: 20px;
background-color: #f5f5f5;
}
</style>
以上两个示例分别是简单的递归树型菜单和带异步加载的递归树型菜单,可以根据自己的实际需求进行修改和拓展。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vuejs实现递归树型菜单组件 - Python技术站