#はじめに
皆さんおはこんばにちは。
エンジニア歴1年目、現場未経験の弱小自称 Web エンジニアです。
今回は、Twitter PC版のように
サイドナビゲーションバーを表示させたまま画面遷移させるべく
試行錯誤した経緯を記録しようと思い、本記事の作成にいたった次第でございます。
#やりたいこと
- リンクをクリックしてページの切り替えをしても、常に左側のドロワーが表示されるようにする
先に結論から述べておくと
ルートの設定を入れ子構造にすれば無事に解決しました。
#最初のコード(失敗例)
特に何の考えもなく実装しようとした最初のコードを以下に記載します。
App.vue
<template>
<v-app>
<v-main>
<router-view />
</v-main>
</v-app>
</template>
<script>
export default {
name: 'App',
};
</script>
Main.vue
<template>
<div>
<SideNav />
<v-content>
<v-container fluid fill-height align-start justify-center>
<router-view />
</v-container>
</v-content>
</div>
</template>
<script>
import SideNav from '../components/SideNav.vue'
export default {
components: {
SideNav,
}
}
</script>
SideNav.vue
<template>
<v-navigation-drawer permanent absolute>
<v-list dense nav>
<v-list-item
v-for="item in items"
:key="item.title"
:to="item.link"
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</template>
<script>
export default {
data() {
return {
items: [
{title: 'ホーム', icon: 'mdi-home', link: {name: 'home'}},
{title: '通知', icon: 'mdi-bell', link: {name: 'notification'}},
{title: 'メール', icon: 'mdi-email', link: {name: 'email'}},
]
}
}
}
</script>
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from '../views/Main.vue'
import Home from '../components/Home.vue'
import Notification from '../components/Notification.vue'
import Email from '../components/Email.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'main',
component: Main,
},
{
path: '/home',
name: 'home',
component: Home,
},
{
path: '/notification',
name: 'notification',
component: Notification,
},
{
path: '/email',
name: 'email',
component: Email,
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
↑GIF画像の通りリンクをクリックした瞬間、ドロワーが消えてしまう!!
リンク先に遷移自体は出来ているようなのに何故……
#試行錯誤の経緯
自分が思い描くドロワーを実装させる為にはどうすれば良いのだろうか。
拙者が無い頭をひねって導き出した対処法は以下の3つ。
① v-navigation-drawer に何かそういうプロパティ無いの??
→ ドキュメントなどを読み漁ったかぎり、見つかりませんでした。
② router-view を App.vue にも Main.vue にも書いているのが不味いの??
→ 名前付きビューってやり方が出て来たけど、何かこれも違いそう。
③ ネスト? そういや Home.vue とかって Main.vue と入れ子構造になってないかな?
→ 予感的中でした!!
#ルートの設定をネストにする
「ホーム画面」「通知画面」「メール画面」
それぞれを形作る Home.vue、Notification.vue、Email.vue は
Main.vue に内包されるコンポーネントになります。
そのため、以下のようにルートの設定を入れ子構造にしてあげることで
目標とする状態へと到達することが出来ました。
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from '../views/Main.vue'
import Home from '../components/Home.vue'
import Notification from '../components/Notification.vue'
import Email from '../components/Email.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'main',
component: Main,
children: [
{ path: 'home', name:'home', component: Home },
{ path: 'notification', name:'notification', component: Notification },
{ path: 'email', name:'email', component: Email },
]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
トライアンドエラーあるのみンゴね〜。
#参考記事
- [Navigation drawers](https://vuetifyjs.com/en/components/navigation-drawers/#navigation-drawers)
- [ネストされたルート](https://router.vuejs.org/ja/guide/essentials/nested-routes.html#%E3%83%8D%E3%82%B9%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E3%83%AB%E3%83%BC%E3%83%88)