🐙

vue.js v-app-barとv-navigation-drawerを使ったハンバーガーメニューをレイアウトのコンポーネントとして作成

2024/08/26に公開

お手柔らかにお願いします。

定番のレイアウトだと思います
vueについてかなり初心者の時に作成してコンポーネントについてかなり勉強になったのでまとめます。

成果物


これを作っていきます

作りたかったもの

ページトップに常設のサイトのタイトル、ハンバーガーメニュー
ナビゲーションドロワーがハンバーガーメニューで出し入れ可能
この二つをコンポーネント化

この条件を満たすものを作成していきます。

フォルダ構造

app.vue
L components
    L layouts
        L titleAndMenuDrawer.vue

app.vueが開かれるとき、titleAndMenuDrawer.vueもページの一部として取り込まれるようにします。

コンポーネントを表示するには

親コンポーネント(app.vue)側

コンポーネントをimportします。
これをしないと表示されません。ご存じの人も多いですかね。

私はあろうことかあまり理解せずコンポーネントを作成していたためコンポーネントを表示するにあたり親コンポーネントにimportを行っていませんでした。

app.vue(html部分)
<template>
  <v-app>
    <titleAndMenuDrawer/>
  </v-app>
</template>
app.vue(script部分)
<script>
import titleAndMenuDrawer from "./components/layouts/title-and-menu-drawer.vue";
export default {
  components: {
    titleAndMenuDrawer,
  }
}
</script>

やっていることとしてはscriptでimportしたtitleAndMenuDrawerをhtml部分の<titleAndMenuDrawer/>で表示しているというイメージです。

最低限これでapp.vueコンポーネントにtitleAndMenuDrawer.vueコンポーネントが子コンポーネントとして取り込まれるようになりました。

子コンポーネント(title-and-menu-drawer.vue)側

読み込む子コンポーネント側について説明します。
今回タイトルとメニューについて作成するのでその画面について作成していきます。

成果物

title-and-menu-drawer.vue(html部分)
<template>
  <div>
    <!-- ヘッダー -->
    <v-app-bar app color="primary" dark>
      <!-- ハンバーガーメニューアイコン -->
      <v-app-bar-nav-icon @click="drawer = !drawer" />
      <!-- ヘッダーのタイトル -->
      <v-toolbar-title>My Application</v-toolbar-title>
      <!-- ヘッダーの右側に表示する内容 -->
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-account</v-icon>
        <!-- 例としてアカウントアイコン -->
      </v-btn>
    </v-app-bar>

    <!-- ナビゲーションドロワー -->
    <v-navigation-drawer
      :mini-variant="miniVariant"
      :clipped="clipped"
      temporary
      v-model="drawer"
      fixed
      app
    >
      <!-- ナビゲーションメニューの内容 -->
      <v-list>
        <v-list-item>
          <v-list-item-title>Menu Item 1</v-list-item-title>
        </v-list-item>
        <v-list-item>
          <v-list-item-title>Menu Item 2</v-list-item-title>
        </v-list-item>
        <!-- 追加のメニューアイテム -->
      </v-list>
    </v-navigation-drawer>

    <!-- メインコンテンツ -->
    <v-main>
      <v-container>
        <slot></slot>
        <!-- 親コンポーネントからのコンテンツを表示 -->
      </v-container>
    </v-main>
  </div>
</template>
title-and-menu-drawer.vue(script部分)
<script>
export default {
  data() {
    return {
      miniVariant: false,
      clipped: true, // ヘッダーとドロワーを連動させる
      drawer: true, // デフォルトでドロワーを開く設定
    };
  },
};
</script>

簡単に言うとこれでタイトルとドロワーが表示されます。
以下でひとつづつ解説していきます。

v-app-ver

app-ver
    <!-- ヘッダー -->
    <v-app-bar app color="primary" dark>
      <!-- ハンバーガーメニューアイコン -->
      <v-app-bar-nav-icon @click="drawer = !drawer" />
      <!-- ヘッダーのタイトル -->
      <v-toolbar-title>My Application</v-toolbar-title>
      <!-- ヘッダーの右側に表示する内容 -->
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-account</v-icon>
        <!-- 例としてアカウントアイコン -->
      </v-btn>
    </v-app-bar>
  • v-app-bar:ヘッダーと表現すればわかりやすいですかね。ページの一番上に表示されるバー状のコンポーネントです。
  • v-app-bar-nav-icon:ハンバーガーメニューを表示しています。
  • v-toolbar-title:タイトルを表示することができます。今回は"My Application"と表示しています。
  • v-spacer:次のアカウントアイコンの右寄せを行うために入れています。
  • v-btn:今はアイコンボタンを表示していますが、場合によっては検索アイコンや詳細などを表示するための︙ボタンを搭載しもいいと思います。

v-spacerやv-btnについては汎用性が高いのでおなじみかもしれなかったですね

v-navigation-drawer

app-ver
    <!-- ナビゲーションドロワー -->
    <v-navigation-drawer
      :mini-variant="miniVariant"
      :clipped="clipped"
      temporary
      v-model="drawer"
      fixed
      app
    >
      <!-- ナビゲーションメニューの内容 -->
      <v-list>
        <v-list-item>
          <v-list-item-title>Menu Item 1</v-list-item-title>
        </v-list-item>
        <v-list-item>
          <v-list-item-title>Menu Item 2</v-list-item-title>
        </v-list-item>
        <!-- 追加のメニューアイテム -->
      </v-list>
    </v-navigation-drawer>

一見複雑そうなことをしているように見えますが意外と単純です。

  • v-navigation-drawer:なんとなくわかるかもしれないですが、ナビゲーションドロワーのスタイルを指定しています。
    • mini-variant:サイドバーをミニバージョン(縮小表示)にするかどうかを制御するプロパティです。trueにすると、サイドバーが縮小され、アイコンだけが表示される状態になります。
    • clipped:このプロパティがtrueに設定されていると、v-toolbarなどの上部に表示されるツールバーが、ナビゲーションドロワーに切り取られたように配置されます。具体的には、ドロワーがツールバーの下に配置されるのではなく、ツールバーの幅に合わせてドロワーがクリップ(切り取られる)される形になります。
    • temporary:temporaryは、ナビゲーションドロワーが一時的な状態で表示されることを意味します。上にかぶさって表示されるイメージです。表示されたときに親コンポーネントに内容をかぶせず表示したい場合はこれを消す必要があります。
    • v-model="drawer":データプロパティを使用して、ドロワーが開いているか閉じているかを制御しています。drawerがtrueの場合、ドロワーが表示され、falseの場合、非表示になります。
    • fixed:trueに設定されていると、ドロワーが固定され、スクロールしても位置が変わりません。
    • app:このプロパティは、ドロワーがアプリケーション全体のレイアウトに影響を与えることを指定します。appが設定されていると、ドロワーのサイズがメインコンテンツのレイアウトに影響を与え、その分メインコンテンツが適切にリサイズされます。
  • v-list:リストを包み込む要素として使用します。
  • v-list-item:リストの各要素に使用します。

最後に

v-navigation-drawer周辺についてはいらないやつを消していけば基本的な要件を満たせるように設計していますので、適度に消してください
以上で作成することができました。
次回以降の記事ではページの遷移を搭載したいと思います。

Discussion