// Tutorial //

Creating a Recursive Tree Component in Vue.js

Published on April 23, 2018
Default avatar
By Alex Jover Morales
Developer and author at DigitalOcean.
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 🦄


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

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>.