
In this snippet i will show you how to render a recursive menu using as recursive component in Vuejs, this is very useful in case you need to render trees of data into dynamic menus or navbars.
Let’s imagine this sample component where we have an array of data that represent the tree we are going to build and we need to loop through this array and display it in a recursive way
Main.vue
<template> <header id="header"><!--header--> <div class="container"> <div class="row"> <div class="col-sm-9"> <div class="mainmenu pull-left"> <ul class="nav navbar-nav collapse navbar-collapse"> <li><router-link to="/" class="active">Home</router-link></li> <li class="dropdown"> <a href="#">Categories<i class="fa fa-angle-down"></i></a> <!-- Render the category tree here ---> </li> </ul> </div> </div> </div> </div> </header> </template> <script> export default { data() { return { categoriesTree: [ { id : 1, title : "Electronics", path: "#", children: [ { id : 2, title : "TVs", path: '/category/2/tvs', children: [] }, { id : 3, title : "Computers", path: '#', children: [ { id: 4, title: 'Dell', path: '/category/4/dell', children: [] }, { id: 5, title: 'HP', path: '/category/5/hp', children: [] } ] } ] }, { id: 6, title : "Fashion", path: '#', children : [ { id: 7, title: 'Men', path: '/category/7/men', children: [] }, { id: 8, title: 'Women', path: '/category/8/women', children: [] } ] }, { id: 9, title: 'Accessories', path: '/category/9/accessories', children: [] } ] } } } </script> <style scoped> </style>
This is a bootstrap navbar and if you look at the categories array which is a tree of categories, each item has an (id, title, path, and children), when the children is not empty then there is a nested item inside. Now we need to render this array as a menu tree in the place you see above identified with this comment <!– Render the category tree here –>.
To do this create another comment call it CategoryTree.vue, this component accept the category data as a prop as shown:
CategoryTree.vue
<template> <ul role="menu"> <li v-for="item in this.dataTree" :key="item.id" :class="{ 'has-nested-menu': item.childrens.length > 0 }"> <a href="#" v-if="item.childrens.length > 0">{{ item.title }}</a> <router-link v-if="item.childrens.length === 0" :to="item.path">{{ item.title }}</router-link> <CategoryTree v-if="item.childrens.length > 0" :dataTree="item.childrens"></CategoryTree> </li> </ul> </template> <script> export default { name: "CategoryTree", props: ["dataTree"] } </script> <style scoped> </style>
This component is a recursive component, as you see we call the <CategoryTree/> inside of itself provided that you give it a name like shown above “CategoryTree“. I pass as prop which is the dataTree.And when we call the component again i pass it the children of the current item if found, this is same technique used in recursive functions.
Update Main.vue component add the <CategoryTree/>
<li class="dropdown"> <a href="#">Categories<i class="fa fa-angle-down"></i></a> <CategoryTree :dataTree="categoriesTree"></CategoryTree> </li>