💻

Nuxt.js+Vuetifyでスマホ対応なイイ感じのナビゲーションを作る

2020/02/14に公開

こんにちは、たつきちです。

エンジニア歴12年ぐらいで今はベンチャー企業のCTOをしています。

この記事では、Nuxt.jsとVuetifyでごくごく一般的な見た目のスマホ対応のサイトを作る場合の、ナビゲーション周りのマークアップについて実例を示しながら解説していきます。

具体的には以下のような見た目のテンプレートを作ります👍

個人的にNuxt.jsもVuetifyも初めて使ってみて結構試行錯誤が必要だったので、備忘録代わりです😅

ぜひ最後までお付き合いください。

Nuxt.js+Vuetifyなプロジェクトの始め方

詳細は 公式ドキュメント をご参照いただければと思いますが、コマンド一発で簡単に始められます🙌

$ npx create-nuxt-app {プロジェクト名}
$ cd {プロジェクト名}
$ npm run dev

npx create-nuxt-app を実行すると、対話形式でプロジェクトの初期化が始まります。

途中で Choose UI framework という質問がありますので、 Vuetify.js を選択しましょう。

テンプレートの内容

細かい話は抜きにして、ぼくのかんがえたさいきょうのテンプレートを書いておきますので、どうぞコピペしてお使いください!

使い方間違えてるよ!とか、もっとエレガントな実装方法があるよ!とかあればぜひ Twitter にコメントください🙏

<!-- layouts/default.vue -->

<template>
  <v-app>
    <v-app-bar
      app
      fixed
      elevate-on-scroll
    >
      <v-container class="d-flex align-center">
        <v-toolbar-title
          class="mr-auto"
          style="cursor:pointer"
          @click="$router.push('/')"
        >
          Title
        </v-toolbar-title>
        <div class="d-none d-md-inline-block">
          <v-btn
            v-for="item in menu"
            :key="item.label"
            :to="item.path"
            text
          >
            {{ item.label }}
          </v-btn>
        </div>
        <v-btn
          class="d-inline-block d-md-none"
          icon
          @click="drawer = !drawer"
        >
          <v-icon>mdi-menu</v-icon>
        </v-btn>
      </v-container>
    </v-app-bar>

    <v-navigation-drawer
      v-model="drawer"
      right
      temporary
      fixed
    >
      <v-list-item
        link
        @click="$router.push('/'); drawer = false"
      >
        <v-list-item-content>
          <v-list-item-title class="title text-center">
            Title
          </v-list-item-title>
        </v-list-item-content>
      </v-list-item>
      <v-divider />
      <v-list
        dense
        nav
      >
        <v-list-item
          v-for="item in menu"
          :key="item.label"
          link
          :to="item.path"
        >
          <v-list-item-icon>
            <v-icon>mdi-menu-right</v-icon>
          </v-list-item-icon>
          <v-list-item-content>
            <v-list-item-title>{{ item.label }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>

    <v-content>
      <v-container>
        <nuxt />
      </v-container>
    </v-content>

    <v-footer>
      <v-container class="d-flex justify-end">
        <span>Title &copy; {{ new Date().getFullYear() }}</span>
      </v-container>
    </v-footer>
  </v-app>
</template>

<script>
export default {
  data () {
    return {
      drawer: false,
      menu: [
        { label: 'MENU 1', path: '/menu1' },
        { label: 'MENU 2', path: '/menu2' },
        { label: 'MENU 3', path: '/menu3' }
      ]
    }
  }
}
</script>
<!-- pages/index.vue -->

<template>
  <p>index</p>
</template>

ところどころ、リンク特有のスタイルが自動付与されてしまうのを防ぐために、 to="" の代わりに @click="$router.push('')" を使ったりしているのがポイントですが、これは本当に正しいのかあまり自信がありません🤔

ともあれ、参考になれば幸いです!

ちなみに、冒頭に貼ったキャプチャ画像は、 こちらの記事 で解説した方法で $container-max-widths の値を変更してあります。

まとめ

  • Nuxt.js+Vuetifyで美しいサイトが簡単に作れる!
  • ぼくのかんがえたさいきょうのテンプレート、よかったら参考にしてみてください!
GitHubで編集を提案

Discussion