Tutorial

Creating a Recursive Tree Component in Vue.js

Published on April 23, 2018
Default avatar

By Alex Jover Morales

Creating a Recursive Tree Component in Vue.js

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Recursion has been always a pain to learn in algorithmics. In some cases however, using recursion feels more natural than using iteration. Traversing a tree is one of them.

We can create recursive components in Vue.js and any other framework by following the same mechanics.

Creating a Tree Component

Imagine a component that must render a tree structure, for example showing a directory tree:

+ Root directory
  + Directory A
    + Directory A1
  + Directory B

We could represent a directory as a Tree, and all subdirectories as a list of Nodes for that tree. A tree has always a root node, which expands untill it reaches the leaf nodes.

For instance, we could use an object with the label and children keys for that:

const tree = {
  label: "A cool folder",
  children: [
    {
      label: "A cool sub-folder 1",
      children: [
        { label: "A cool sub-sub-folder 1" },
        { label: "A cool sub-sub-folder 2" }
      ]
    },
    { label: "This one is not that cool" }
  ]
}

Given the previous structure, let’s create a Tree.vue component that takes it as a prop and renders the root node:

Tree.vue
<template>
  <div class="tree">
    <ul class="tree-list">
      <node-tree :node="treeData"></node-tree>
    </ul>
  </div>
</template>

<script>
import NodeTree from "./NodeTree";

export default {
  props: {
    treeData: Object
  },
  components: {
    NodeTree
  }
};
</script>

<style>
.tree-list ul {
  padding-left: 16px;
  margin: 6px 0;
}
</style>

We’re adding some padding to the left of the lists, so they have that hierarchical look.

Nothing special happening here, we’re just getting a treeData property and passing it as the first node to a NodeTree component that we have yet to implement.

Implementing the Node Tree

A Node Tree must show its label, but at the same time it must render its children. In that way, a NodeTree is also a sub-tree.

A simple NodeTree.vue component would be:

NodeTree.vue
<template>
  <li class="node-tree">
    <span class="label">{{ node.label }}</span>
  </li>
</template>

<script>
export default {
  props: {
    node: Object
  }
};
</script>

But the component just shows a label, we still have to make it render its children, which are also tree nodes.

If you think about it, it’s the same case than recursive functions; they’re functions that call themselves as long as a condition is not fulfilled.

So, we have to make the node tree render a list of node trees. In order to access a component from the same component, we have to add the name component option:

NodeTree.vue
<template>
  <li class="node-tree">
    <span class="label">{{ node.label }}</span>

    <ul v-if="node.children && node.children.length">
      <node v-for="child in node.children" :node="child"></node>
    </ul>
  </li>
</template>

<script>
export default {
  name: "node",
  props: {
    node: Object
  }
};
</script>

That will make the NodeTree component call itself until it reaches the leaf node.

As you can see, we’re using name: "node" thus the <node> tag. The children tree nodes are only rendered when there are children, passing the child node as their property.

Using the Tree Component

In order to try it out, for instance, you can create an App.vue component passing the previous data structure to the Tree component:

App.vue
<template>
  <div>
    <tree :tree-data="tree"></tree>
  </div>
</template>

<script>
import Tree from "./Tree";

export default {
  data: () => ({
    tree: {
      label: "A cool folder",
      children: [
        {
          label: "A cool sub-folder 1",
          children: [
            { label: "A cool sub-sub-folder 1" },
            { label: "A cool sub-sub-folder 2" }
          ]
        },
        { label: "This one is not that cool" }
      ]
    }
  }),
  components: {
    Tree
  }
};
</script>

Wrapping Up

Recursion doesn’t have to be hard, and Vue.js makes it a breeze by giving support from its DSL or template.

I hope that this article will help you build awesome Tree components!

Stay cool 🦄

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Alex Jover Morales

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Clean and simple, thanks! I just had to add [0] to access the array in the object.

Laravel Eloquent benefiters may want to do,

<node v-for="child in node.children_recursive" :node="child"></node>.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel