vuejs实现递归树型菜单组件

yizhihongxing

下面是详细讲解“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技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • python中的变量如何开辟内存

    Python中的变量如何开辟内存 在Python中,变量是用来存储数据的标识符。当我们创建一个变量时,Python会为其分配内存空间来存储数据。下面是Python中变量开辟内存的详细过程: 变量声明:在Python中,我们可以通过简单的赋值语句来声明变量。例如,x = 10就是声明了一个变量x,并将其赋值为10。 对象创建:在变量声明时,Python会根据变…

    other 2023年8月2日
    00
  • sed使用删除匹配行

    以下是详细讲解“sed使用删除匹配行的完整攻略,过程中至少包含两条示例说明”的标准Markdown格式文本: sed使用删除匹配行 sed是一种流编辑器,可以用于对文本进行编辑和转换。其中,删除匹配行是sed的一种常见用法。本攻略将介绍如何使用sed删除匹配行,包括基本语法和常用选项。同时,本攻略还提供了两个示例说明,帮助您更好地理解和应用这些技术。 基本语…

    other 2023年5月10日
    00
  • Spring中的bean概念介绍

    当谈到Spring框架时,“bean”一定是其中最重要的概念之一。Bean是指一个由Spring容器中管理的对象,可以是任何类的实例,通常表示应用程序的业务逻辑或实现。在Spring中,Bean是通过IoC(Inversion of Control)技术实现的。 什么是Bean? Bean是Spring中的一个组件,是管理对象以及自动装配的基本单元。Bean…

    other 2023年6月27日
    00
  • 【图机器学习】cs224w Lecture 16 – 图神经网络的局限性

    【图机器学习】cs224w Lecture 16 – 图神经网络的局限性 引言 图神经网络(Graph Neural Network, GNN)是近年来研究最为火热的机器学习领域之一,该领域的研究成果已经被广泛应用于社交网络、生物信息学、自然语言处理等多个领域。然而,尽管GNN有着非凡的表现,但是它们并不是完美的,因为它们存在着一些局限性。 在本文中,我们将…

    其他 2023年3月28日
    00
  • Java基础复习笔记系列 五 常用类

    Java基础复习笔记系列 五 常用类 在 Java 编程语言中,有一些常用的类被广泛使用,例如 String、Math、Date 等。这些类是 Java 核心库中的一部分,开发者可以直接使用这些类,而无需自己手动实现。本篇文章将介绍一些常用的类及其使用方法。 String 类 Java 中的 String 类表示不可变的字符串,常用于字符串拼接、操作、比较等…

    其他 2023年3月28日
    00
  • 正则表达式常用元字符整理小结

    正则表达式常用元字符是指在正则表达式中具有特殊含义的字符。它们被用于匹配文本中的不同类型的字符。 以下是常用的元字符整理小结: ^:匹配字符串的开始位置,在中括号中表示取反匹配。 $:匹配字符串的结束位置。 .:匹配任意字符,不包括换行符。 *:匹配前一个字符的0个或多个,可以理解为贪婪匹配。 +:匹配前一个字符的1个或多个,也是贪婪匹配。 ?:匹配前一个字…

    other 2023年6月20日
    00
  • apache后缀名支持 让apache支持apk ipk下载的方法

    Apache后缀名支持:让Apache支持APK和IPK下载的方法 Apache是一种常用的Web服务器软件,它可以用于提供文件下载服务。默认情况下,Apache只支持一些常见的文件后缀名,如HTML、CSS和JavaScript等。如果你想让Apache支持APK和IPK文件的下载,你需要进行一些配置。 以下是让Apache支持APK和IPK下载的完整攻略…

    other 2023年8月5日
    00
  • Android通过aapt命令获取apk详细信息(包括:文件包名,版本号,SDK等信息)

    Android通过aapt命令获取APK详细信息 aapt是Android Asset Packaging Tool的缩写,它是Android SDK中的一个命令行工具,用于处理APK文件。通过使用aapt命令,我们可以获取APK文件的详细信息,包括文件包名、版本号、SDK等信息。下面是获取APK详细信息的完整攻略。 步骤一:安装Android SDK 首先…

    other 2023年8月3日
    00
合作推广
合作推广
分享本页
返回顶部