- CSSはBootstrapを利用しています
template
<template>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">サイト名</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item" v-for="level1Menu in showMenu" :key="level1Menu.name">
<a class="nav-link " href="#" role="button" @click="level1Toggle(level1Menu)">
{{level1Menu.name}}
</a>
<ul class="dropdown-menu" style="display: block;" v-show="level1Menu.show_menu">
<li v-for="item in level1Menu.menu" :key="item.name">
<router-link :to="item.to" class="dropdown-item" @click="toggle(item)">{{item.name }}</router-link>
<ul v-show="item.showChildren">
<li v-for="child in item.children" :key="child.name">
<router-link :to="child.to" class="dropdown-item" @click="toggle(child)">{{child.name }}</router-link>
<ul v-show="child.showChildren">
<li v-for="grandchild in child.children" :key="grandchild.name">
{{ grandchild.name }}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</template>
script
<script setup>
import { ref } from 'vue'
const level1Toggle=(target)=>{
const prevState = target.show_menu
resetAll()
//prevState : true->falseの場合は処理しない
if(!prevState)
target.show_menu = !target.show_menu
}
const resetAll =()=>{
Object.keys(showMenu.value).forEach(i=>{
showMenu.value[i].show_menu = false
})
}
const menuItem1 = ref([
{ name: "子メニュー1",showChildren: false,to:"/abc",},
{ name: "子メニュー2", showChildren: false ,to:"/def",},
{ name: "子メニュー3", showChildren: false ,to:"/ghi",}
])
const menuItem2 = ref([
{ name: "子メニュー4", showChildren: false,to:"/aaaa" },
{
name: "子メニュー5",
showChildren: false,
to:"/",
children: [
{name: "孫メニュー1",showChildren: false,to:"/a"},
{name: "孫メニュー2",showChildren: false,to:"/b"},
{name: "孫メニュー3",showChildren: false,to:"/c"},
]
},
{ name: "子メニュー6", showChildren: false,to:"/" },
{ name: "子メニュー7", showChildren: false,to:"/",children: [
{name: "孫メニュー4",showChildren: false,to:"/"},
{name: "孫メニュー5",showChildren: false,to:"/"},
]
},
{ name: "子メニュー8", showChildren: false,to:"/aaaa" },
])
const menuItem3 = ref([
{ name: "子メニュー9", showChildren: false,to:"/b" },
{ name: "子メニュー10", showChildren: false,to:"/c" },
])
const menuItem4 = ref([
{ name: "子メニュー11", showChildren: false,to:"/d" },
])
const showMenu = ref([
{name:"メニュー1",menu:menuItem1,show_menu:false},
{name:"メニュー2",menu:menuItem2,show_menu:false},
{name:"メニュー3",menu:menuItem3,show_menu:false},
{name:"メニュー4",menu:menuItem4,show_menu:false},
])
const toggle = (item) => {
item.showChildren = !item.showChildren
}
</script>
最後
一応コピーでも動くはずです。さらに孫メニューのデータにchildrenを増やせば曽孫メニューも出せます。
Vue.jsは使い始めて数ヶ月のため、書き方的に正しくないかもしれませんので、気になる箇所があれば、ぜひともご指摘いただければ幸いです。
現段階は「動く」を優先にしています