This article mainly introduces the teaching content of using Vue.js recursive components to build a collapsible tree menu. Friends who are interested can follow along.
In Vue.js a recursive component calls itself, such as:
Vue.component('recursive-component', { template: `<!--Invoking myself!--> <recursive-component></recursive-component> });
Recursive components are often used to display comments, nested menus on blogs, or basically parent and child Same type, although the specifics are different. For example:
Now I will show you how to use recursive components effectively. I will proceed step by step by building an expandable/collapse tree menu.
Data Structure
A recursive component of a tree UI will be a visual representation of some recursive data structure. In this tutorial, we will use a tree structure, where each node is an object:
a label property.
If it has child nodes, a nodes attribute, then it is an array attribute of one or more nodes.
Like all tree structures, it must have a root node, but can be infinitely deep.
let tree = { label: 'root', nodes: [ { label: 'item1', nodes: [ { label: 'item1.1' }, { label: 'item1.2', nodes: [ { label: 'item1.2.1' } ] } ] }, { label: 'item2' } ] }
Recursive Component
Let’s make a recursive component to display our data structure called TreeMenu. It only displays the current node's label, and calls itself to display any child nodes. File name: TreeMenu.vue, the content is as follows:
<template> <p class="tree-menu"> <p>{{ label }}</p> <tree-menu v-for="node in nodes" :nodes="node.nodes" :label="node.label" > </tree-menu> </p> </template> <script> export default { props: [ 'label', 'nodes' ], name: 'tree-menu' } </script>
If you use a component recursively, you must first make a global definition for Vue.component, or give it a name attribute. Otherwise, any child component will not be able to call it further and you will get an undefined "undefined component error" error message.
Basic Event
As with any recursive function, you need a basic event to end the recursion, otherwise rendering will continue indefinitely, eventually causing a stack overflow.
In the tree menu, we want to stop the recursion when we reach a node that has no children. You can do this via v-if , but our choice to use v-for will implicitly implement it for us; if the nodes array doesn't have any further definitions the tree-menu component will be called. The template.vue file is as follows:
<template> <p class="tree-menu"> ... <!--If `nodes` is undefined this will not render--> <tree-menu v-for="node in nodes"></tree-menu> </template>
Usage
How do we use this component now? First, we declare a Vue instance with a data structure including the data attribute and the defined treemenu component. The app.js file is as follows:
import TreeMenu from './TreeMenu.vue' let tree = { ... } new Vue({ el: '#app', data: { tree }, components: { TreeMenu } })
Remember, our data structure has a root node. We start recursively calling the TreeMenu component in the main template, using the root nodes attribute to props:
<p id="app"> <tree-menu :label="tree.label" :nodes="tree.nodes"></tree-menu> </p>
Here is what it currently looks like:
Correct posture
It's good to visually identify the "depth" of subcomponents so users can get a feel for the data structure from the UI. Let's achieve this by indenting the child nodes at each level.
This is achieved by adding a depth prop definition through TreeMenu. We will use this value to dynamically bind inline styles with transforms: we will use the transform: translate CSS rule for each node's label, thus creating an indent. template.vue is modified as follows**:**
<template> <p class="tree-menu"> <p :style="indent">{{ label }}</p> <tree-menu v-for="node in nodes" :nodes="node.nodes" :label="node.label" :depth="depth + 1" > </tree-menu> </p> </template> <script> export default { props: [ 'label', 'nodes', 'depth' ], name: 'tree-menu', computed: { indent() { return { transform: `translate(${this.depth * 50}px)` } } } } </script>
depth attribute starts from zero in the main template. In the component template above, you can see that this value is incremented every time it is passed to any child node.
<p id="app"> <tree-menu :label="tree.label" :nodes="tree.nodes" :depth="0" ></tree-menu> </p>
Note: Remember to v-bind the depth value to make sure it is a JavaScript number type and not a string.
Expand/Collapse
Since recursive data structures can be large, a good UI trick for displaying them is to hide all nodes except the root node so that the user can Nodes need to be expanded or collapsed.
To do this, we will add a local attribute showChildren. If its value is False, the child node will not be rendered. This value should be toggled by clicking on the node, so we need to use a click event listener method toggleChildren to manage it. The template.vue file is modified as follows**: **
<template> <p class="tree-menu"> <p :style="indent" @click="toggleChildren">{{ label }}</p> <tree-menu v-if="showChildren" v-for="node in nodes" :nodes="node.nodes" :label="node.label" :depth="depth + 1" > </tree-menu> </p> </template> <script> export default { props: [ 'label', 'nodes', 'depth' ], data() { return { showChildren: false } }, name: 'tree-menu', computed: { indent() { return { transform: `translate(${this.depth * 50}px)` } } }, methods: { toggleChildren() { this.showChildren = !this.showChildren; } } } </script>
Summary
In this way, we have a working tree menu. As a finishing touch, you can add a plus/minus icon to make the UI more visible. I also added great font and computing capabilities to the original showChildren.
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
Related articles:
How to implement mouse-responsive Taobao animation effect in jQuery
JQuery-implemented mouse response buffer animation effect
How to implement vue2.0 responsiveness (detailed tutorial)
How to achieve text intermittent cycle scrolling effect through JS
Explain in detail refs in React (detailed tutorial)
The above is the detailed content of How to build a tree menu through recursive components in Vue.js. For more information, please follow other related articles on the PHP Chinese website!

VueUse 是 Anthony Fu 的一个开源项目,它为 Vue 开发人员提供了大量适用于 Vue 2 和 Vue 3 的基本 Composition API 实用程序函数。本篇文章就来给大家分享几个我常用的几个 VueUse 最佳组合,希望对大家有所帮助!

Vue3如何更好地使用qrcodejs生成二维码并添加文字描述?下面本篇文章给大家介绍一下Vue3+qrcodejs生成二维码并添加文字描述,希望对大家有所帮助。

本篇文章给大家整理分享8个GitHub上很棒的的 Vue 项目,都是非常棒的项目,希望当中有您想要收藏的那一个。

本篇文章带大家聊聊vue指令中的修饰符,对比一下vue中的指令修饰符和dom事件中的event对象,介绍一下常用的事件修饰符,希望对大家有所帮助!

如何使用VueRouter4.x?下面本篇文章就来给大家分享快速上手教程,介绍一下10分钟快速上手VueRouter4.x的方法,希望对大家有所帮助!

如何覆盖组件库样式?下面本篇文章给大家介绍一下React和Vue项目中优雅地覆盖组件库样式的方法,希望对大家有所帮助!


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 English version
Recommended: Win version, supports code prompts!

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools
