用 Vue.js 递归组件实现可折叠的树形菜单(demo)

yizhihongxing

首先我们需要明确一下什么是递归组件。顾名思义,递归组件就是在组件内部使用该组件本身。在树形结构的数据展示中,经常会使用到递归组件来展示子节点。

接下来我将以“用 Vue.js 递归组件实现可折叠的树形菜单(demo)”为例,讲解一下如何使用递归组件来实现树形菜单的效果。

  1. 定义组件

首先我们需要定义一个组件,用于展示每一个菜单项。该组件需要有以下特点:

  • 显示菜单文字
  • 点击可展开/折叠子菜单
  • 当前菜单被选中时需要高亮

我们将该组件命名为Menu:

<template>
  <li>
    <div @click="toggleShowChildren">
      <span :class="{ 'active': isActive }">{{menuItem.name}}</span>
      <span v-if="menuItem.children" :class="{ 'arrow': true, 'down': showChildren, 'right': !showChildren }"></span>
    </div>
    <ul v-show="showChildren">
      <menu-item v-for="(item, index) in menuItem.children" :key="index" :menu-item="item" :deep="deep+1"></menu-item>
    </ul>
  </li>
</template>

<script>
export default {
  name: 'MenuItem',
  props: {
    menuItem: Object,
    deep: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      showChildren: false
    }
  },
  computed: {
    isActive() {
      return this.menuItem.active
    }
  },
  methods: {
    toggleShowChildren() {
      if (this.menuItem.children) {
        this.showChildren = !this.showChildren
      }
    }
  },
  components: {
    MenuItem
  }
}
</script>

<style>
.active {
  color: red;
}

li .arrow {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 5px;
  border-top: 4px solid transparent;
  border-right: 5px solid;
  border-bottom: 4px solid transparent;
  vertical-align: middle;
  cursor: pointer;
}

li .arrow.down {
  border-top: 4px solid;
  border-right: 5px solid transparent;
  border-bottom: 4px solid transparent;
}

ul {
  margin-left: 10px;
  padding: 0;
  list-style: none;
  border-left: 1px solid #ccc;
}

li {
  padding: 5px 0;
  position: relative;
}
</style>

在该组件中,我们使用了递归的方式展示菜单的子节点。循环遍历传入的menuItem.children数组,如果该菜单项有子菜单,则将该子菜单传入Menu组件中进行展示。

  1. 使用递归组件

接下来,我们需要引入顶层的菜单组件,并传入菜单数据。

<template>
  <div class="app">
    <ul>
      <menu-item v-for="(item, index) in menuData" :key="index" :menu-item="item"></menu-item>
    </ul>
  </div>
</template>

<script>
import MenuItem from './components/MenuItem.vue'

export default {
  components: {
    MenuItem
  },
  data() {
    return {
      menuData: [
        {
          name: '菜单1',
          active: false,
          children: [
            {
              name: '菜单1-1',
              active: false,
              children: [
                {
                  name: '菜单1-1-1',
                  active: false,
                },
                {
                  name: '菜单1-1-2',
                  active: false,
                }
              ]
            },
            {
              name: '菜单1-2',
              active: false,
            }
          ]
        },
        {
          name: '菜单2',
          active: false,
          children: [
            {
              name: '菜单2-1',
              active: false
            },
            {
              name: '菜单2-2',
              active: false
            }
          ]
        }
      ]
    }
  }
}
</script>

<style scoped>
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
</style>

在该组件中,我们引入了MenuItem,并将根菜单数据menuData传入到MenuItem中进行渲染。

  1. 显示菜单高亮

要实现显示菜单高亮效果,我们需要使用Vue.js中的路由功能。首先我们需要引入Vue Router,并在router/index.js中定义好路由规则。

然后,在Menu组件中,我们需要判断当前菜单项是否与路由信息相符。如果相符,则将该菜单项设置为选中状态。代码如下所示:

<script>
import { mapState } from 'vuex'

export default {
  name: 'MenuItem',
  props: {
    menuItem: Object,
    deep: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      showChildren: false
    }
  },
  computed: {
    ...mapState({
      currentPath: state => state.route.path
    }),
    isActive() {
      return this.menuItem.active
    }
  },
  methods: {
    toggleShowChildren() {
      if (this.menuItem.children) {
        this.showChildren = !this.showChildren
      }
    }
  },
  components: {
    MenuItem
  },
  watch: {
    currentPath() {
      if (this.menuItem.path === this.currentPath) {
        this.menuItem.active = true
      } else {
        this.menuItem.active = false
      }
    }
  }
}
</script>

在上述代码中,我们引入了Vuex中的mapState方法,获取当前路由信息currentPath。然后,在watch中监听路由信息变化,判断当前菜单项的路由信息是否与当前路由信息相同。如果相同,将该菜单项设置为选中状态。

综上所述,以上是用Vue.js递归组件实现可折叠的树形菜单(demo)的完整攻略。其中包括了组件的定义、递归调用、显示高亮等功能。您可以参考代码进行实践,也可以在此基础上进行二次开发。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用 Vue.js 递归组件实现可折叠的树形菜单(demo) - Python技术站

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

相关文章

  • pandasinfo函数

    pandas.info()函数是pandas库中的一个函数,用于显示DataFrame对象的基本信息,包括每列的名称、非空值的数量、数据类型和内存使用情况等。以下是使用pandas.info()函数的完整攻略: 步骤1:导入pandas库 在使用pandas.info()函数之前,需要先导入pandas库。可以使用以下代码导入pandas库: import …

    other 2023年5月7日
    00
  • Vue使用video.js的代码详解

    下面将详细讲解Vue使用video.js的代码详解及其完整攻略。 什么是Vue Vue是当前较为流行的前端框架之一,它采用MVVM的模式,使得数据和UI的双向绑定显得更加简单和快捷。 什么是video.js video.js是一款开源的HTML5视频播放器,可以进行二次开发以满足开发者的需求,比浏览器自带的HTML5播放器具有更好的兼容性和支持性。 在Vue…

    other 2023年6月27日
    00
  • 好人共享的一个万能Ghost系统制作教程附相关软件下载

    好人共享的一个万能Ghost系统制作教程 一、下载相关软件 Ghost系统镜像文件:从好人共享或官方网站下载 U盘制作工具rufus:从官方网站下载 二、制作U盘启动盘 将U盘插入电脑,运行rufus。在程序界面中选择对应的ISO镜像文件,并确认U盘的正确路径。可以在选项中进行一些基础设置,如分区类型、文件系统等等。 点击开始制作按钮,等待制作完成。 示例说…

    other 2023年6月27日
    00
  • Android LayoutInflater加载布局详解及实例代码

    Android LayoutInflater加载布局详解及实例代码攻略 在Android开发中,LayoutInflater是一个用于将XML布局文件转换为对应的View对象的类。它允许我们在代码中动态地加载布局,从而实现更灵活的界面设计。下面将详细讲解LayoutInflater的使用方法,并提供两个示例说明。 1. 获取LayoutInflater对象 …

    other 2023年8月20日
    00
  • Android虚拟机与类加载机制详情

    Android虚拟机与类加载机制 什么是Android虚拟机 Android虚拟机是为了在计算机上模拟Android系统环境,方便开发者开发和测试安卓应用程序的工具。目前Android系统所用的虚拟机主要是Dalvik和ART两种。 Dalvik虚拟机 Dalvik虚拟机是Google在Android系统中使用的Java虚拟机,它使用了一种叫做DEX的字节码…

    other 2023年6月25日
    00
  • 如何用eclipse运行导入的maven项目

    以下是详细讲解“如何用Eclipse运行导入的Maven项目”的完整攻略,过程中至少包含两条示例说明的标准Markdown格式文本: 如何用Eclipse运行导入的Maven项目 Maven是一款常用的Java项目管理工具,而Eclipse是一款常用的Java集成开发环境。本文将介绍如何在Eclipse中运行导入的Maven项目。 步骤一:导入Maven项目…

    other 2023年5月10日
    00
  • linux-expr:cygwin中的非整数参数错误

    在Cygwin中,当使用expr命令进行数学计算时,可能会遇到“expr: non-integer argument”错误。这个错误通常是由于使用了非整数参数而引起的。本文将提供完整的攻略,解决这个问题,并提供两个示例说明。 步骤1:检查参数是否为整数 首先,我们需要检查使用的参数是否为整数。expr命令只能处理整数,如果使用了非整数参数,则会出现“expr…

    other 2023年5月8日
    00
  • iOS 14.4/iPadOS 14.4(18D5030e)开发者预览版 Beta值得更新吗?

    iOS 14.4/iPadOS 14.4(18D5030e)开发者预览版 Beta值得更新吗? 如果你是 iOS/iPadOS 平台的开发者并且想获取最新的系统测试,那么 iOS/iPadOS 14.4 开发者预览版可能值得你的注意。 1. 更新内容 首先,我们来看看 iOS/iPadOS 14.4 开发者预览版带来的更新内容: 新增了“设备类型”信息,可以…

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