0

I am using Vue and I have the array of objects and I need to use it to create a menu using that.

The array list looks like the following:

[{
    "name": "Menu 1",
    "url": "/link/menu-1",
    "sub-menus": []
},
{
    "name": "Menu 2",
    "url": "/link/menu-2",
    "sub-menus": [
        {
            "name": "Menu 2-1",
            "url": "/link/menu-2-1",
            "sub-menus": []
        },
        {
            "name": "Menu 2-2",
            "url": "/link/menu-2-2",
            "sub-menus": []
        }
    ]
},
{
    "name": "Menu 3",
    "url": "/link/menu-3",
    "sub-menus": [
        {
            "name": "Menu 3-1",
            "url": "/link/menu-2-1",
            "sub-menus": [
                {
                    "name": "Menu 3-1-1",
                    "url": "/link/menu-3-1-1",
                    "sub-menus": []
                }
            ]
        },
        {
            "name": "Menu 3-2",
            "url": "/link/menu-2-2",
            "sub-menus": []
        }
    ]
}]

Since there are multiple sub-menu levels, I have no idea how to generate the menu dynamically.

The level of sub-menu is not fixed. It can be no sub-menu or more than 2 or 3 levels.

I want the output to be something like the following.

<ul>
<li>
    <a href="/link/menu-1">Menu 1</a>
</li>
<li>
    <a href="/link/menu-2">Menu 2</a>
    <ul>
        <li>
            <a href="/link/menu-2-1">Menu 2-1</a>
        </li>
        <li>
            <a href="/link/menu-2-2">Menu 2-2</a>
        </li>
    </ul>
</li>
</ul>

Since i am new to Vue, i have no idea how this can be achieved. Thanks in advance.

2 Answers 2

1

I think you can do it with two components.

One that will build a menu for itself and it's sub ones :

var Menu = ({
  name:"Menu",

  template: `
    <li>
        <a :href="url">{{name}}</a>

        <ul v-if="subMenus.length > 0">
          <Menu 
            v-for="menu in subMenus" 
            :name="menu.name" 
            :url="menu.url" 
            :subMenus="menu['sub-menus']">
          </Menu>
        </ul>
    </li>`,

  props: {
    name:     {type:String, required:true},
    url:      {type:String, required:true},
    subMenus: {type:Array, required:true}
  }
})

And another one to insantiate everything, that will iterate over your menu list (that you will pass as a prop) :

var FullMenu = ({ 
  components: {Menu},

  name:"FullMenu", 

  template: `
    <div>
      <ul>
        <Menu 
          v-for="menu in menus" 
          :name="menu.name" 
          :url="menu.url" 
          :subMenus="menu['sub-menus']">
        </Menu>
      </ul>
    </div>
    `,

  props: {
    menus: {type:Array, required:true}
  }
})

Just use it like this:

<div>
  <full-menu :menus="yourMenuListAsDataOrProps"></full-menu>
</div>`

Here is a running example on Observable : https://observablehq.com/d/802261a535698d88#FullMenu

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I will try your method and let you know.
0

i fixed this issue like below way:

use this in template section =>

<span v-html="hasChild(chart)"></span>

and hasChild method =>

hasChild(chart){
  var html = ''
  if(chart.childs.length>0){
    html = html+'<ul>'
    chart.childs.map(child=>{
      html = html+'<li>'
      html = html+'<a>'+child.title+'</a>'
      if(child.childs.length>0){
        html = html+this.hasChild(child)
      }
      html = html+'</li>'
    })
    html = html+'</ul>'
    return html
  }
}

and work fine for me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.