はじめに
グローバルメニューにホバーした時やクリックしたときにしたタブを出して、ページ誘導を試みる実装をしていて少し詰まったので記事として共有してみます。
Nuxt(Vue)で本記事のような内容は見受けられなかったので、皆さんのお役に立てれば幸いです。
また、本記事はVuetifyを使用しています。
では、さっそく内容に迫っていきましょう。
最終イメージ【グローバルメニュー】
スタート【グローバルメニュー】
まずはVuetifyのAppBar部分をいじっていきます。
<v-app-bar
v-scroll="onScroll"
app
dark
elevate-on-scroll
>
<v-img
v-if="isScrolling || $route.name!=='index'"
class="shrink"
max-width="60%"
width="65"
src="/home.png"
@click="$router.push('/')"
/>
<v-spacer />
<v-toolbar-items v-if="$vuetify.breakpoint.mdAndUp">
<template v-for="item in items">
<v-btn
v-if="!item.math"
:key="item.id"
:active-class="!isScrolling && $route.name==='index' ? 'primary--text' : undefined"
:to="item.to"
text
v-text="item.text"
/>
<v-menu
v-else
:key="item.id"
bottom
offset-y
:open-on-hover="true"
:open-on-click="false"
>
<template v-slot:activator="{on}">
<v-btn text v-on="on">
<span>{{ item.text }}</span>
<v-icon>mdi-menu-down</v-icon>
</v-btn>
</template>
<v-list>
<template v-for="(math,i) in item.math">
<v-divider v-if="math.divider" :key="i" />
<v-list-item v-else :key="math.id" :to="math.to">
<v-list-item-title :style="'font-size:0.9rem'" class="mr-2">
{{ math.title }}
</v-list-item-title>
<v-icon
:color="math.color"
size="26"
v-text="math.icon"
/>
</v-list-item>
</template>
</v-list>
</v-menu>
</template>
</v-toolbar-items>
<v-app-bar-nav-icon
v-else
aria-label="Open Navigation Drawer"
@click="toggleDrawer"
/>
</v-app-bar>
export default {
data: () => ({
isScrolling: false,
hoverFlag: false,
items: [
{
to: '/',
text: '国語'
},
{
text: '数学',
math: [
{
title: '数IA',
icon: 'mdi-chevron-right',
color: 'primary',
to: '/math/math_one-a'
},
{ divider: true, inset: true },
{
title: '数ⅡB',
icon: 'mdi-chevron-right',
color: 'primary',
to: '/math/math_two_b'
},
{ divider: true, inset: true },
{
title: '数ⅢC',
icon: 'mdi-chevron-right',
color: 'primary',
to: '/math/math_three_c'
}
]
},
{
to: '/english',
text: '英語'
},
{
to: '/society',
text: '社会'
}
]
})
methods: {
onScroll () {
this.isScrolling = (window.pageYOffset ||
document.documentElement.scrollTop || 0) > 25
}
}
}
* storeを利用している部分は省略して記載しております。
最終イメージ【レスポンシブ】
スタート【ドロワーメニュー】
まずはVuetifyのv-navigation-drawer部分をいじっていきます。
<v-navigation-drawer
v-model="inputValue"
fixed
right
temporary
>
<v-row
align="center"
class="ma-0 pa-3 flex-no-wrap"
>
<v-spacer />
<v-btn
aria-label="Close"
class="ml-4"
icon
@click="toggleDrawer"
>
<v-icon>mdi-close</v-icon>
</v-btn>
</v-row>
<v-divider />
<v-list>
<template v-for="item in items">
<v-list-item
v-if="!item.lists"
:key="item.id"
:to="item.to"
@click="menuClose"
>
<v-list-item-content>
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-group
v-else
:key="item.id"
v-model="item.active"
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="(math,i) in item.lists"
:key="i"
:to="math.to"
>
<v-list-item-title class="ml-6">
<v-icon :color="math.color" class="mr-3" v-text="math.icon" />
{{ math.name }}
</v-list-item-title>
</v-list-item>
</v-list-group>
</template>
</v-list>
</v-navigation-drawer>
export default {
data: () => ({
items: [
{
to: '/',
text: '国語'
},
{
text: '数学',
active: false,
lists: [{
name: '数IA',
to: '/math/math_one_a',
icon: 'mdi-chevron-right',
color: 'primary'
},
{
name: '数ⅡB',
to: '/math/math_two_b',
icon: 'mdi-chevron-right',
color: 'primary'
},
{
name: '数ⅢC',
to: '/math/math_three_c',
icon: 'mdi-chevron-right',
color: 'primary'
}
]
},
{
to: '/english',
text: '英語'
},
{
to: '/society',
text: '社会'
}
]
}),
computed: {
inputValue: {
get () {
return this.drawer
},
set (val) {
this.setDrawer(val)
}
}
},
methods: {
menuClose () {
this.items.forEach((item) => { item.active = false })
}
}
}
* storeを利用している部分は省略して記載しております。
おわりに
下タブ(詳細URL)を使うときはV-ifでの条件分岐によって、上手く実装することがポイントでした。
具体的にはv-list-itemとv-list-groupを分ける。v-list-groupで一つにまとめると挙動が異なるので注意しなければいけませんでした。
少しでもお役手に立てればLGTMをお願い致します🙇♂️