はじめに
前回の続きの記事となります。
今回はVuetifyでPCのヘッダーのナビゲーションを作成していきます。
完成イメージは下記の通りです。
本記事の内容
■ ナビゲーションメニューの作成方法
■ Vuetifyで生成されたクラスのスタイルを直接修正する方法
■ グローバルなscssファイルをあらかじめ読み込ませる方法
■ メディアクエリを使用したレスポンシブなヘッダーメニューを作成する方法
Contents
ナビゲーションメニューの作成
下図のようなナビゲーションメニューを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<v-app-bar app dark > <v-app-bar-nav-icon @click="drawer = true"></v-app-bar-nav-icon> <v-toolbar-title>MyPortfolioSite</v-toolbar-title> <!-- ここから追加 --> <v-tabs> <v-tab v-for="(menuItem, index) in menuItems" :key="index" > {{ menuItem.name }} </v-tab> </v-tabs> <!-- ここまで追加 --> </v-app-bar> |
作業内容
① v-tabs
タグ追加
② v-tab
タグを追加し、v-for
ディレクティブでメニューの各アイテム表示
v-tabsタグ
v-tabs
タグは以下のような構造になっており、v-tabs
タグを使用することで簡単にナビゲーションメニューを作成することができます。
コーディングする際は、以下のように書きましょう。
1 2 3 4 5 |
<v-tabs> <v-tab>アイテム1</v-tab> <v-tab>アイテム2</v-tab> <v-tab>アイテム3</v-tab> </v-tabs> |
今回のサンプルプログラムでは、v-tab
タグ内はメニュー名が異なるだけで要素は同じであるため、前回データ定義したmenuItems
を利用して、v-for
ディレクティブで繰り返し処理を行なっております。
v-tabs
タグをカスタマイズしたい方はv-tabsの公式ドキュメントを参考に様々なオプションを試してみてください。
ヘッダータイトルのスタイルの修正
スタイルを修正しなければ、下図のようにヘッダータイトルの一部が隠れてしまってしまいます。
これを回避するためにスタイルを修正していきます。
1 2 3 4 5 6 7 8 |
<!-- ここから修正 --> <style lang="scss" scoped> .v-toolbar__title { overflow: visible !important; margin-right: 50px !important; } </style> <!-- ここまで修正 --> |
作業内容
① style
タグにlang="scss"
とscoped
属性追加
② Vuetifyで生成されたクラスのスタイルを修正
styleタグの修正
今回styleタグに追加した属性について解説します。
lang=”XXX” | どの言語でcssを記述するかを記載する。XXX部分にはcss・scss・postcss のいずれかを設定。今回はscss を使用しているため、lang="scss" と記載している。 |
---|---|
scoped | scoped 属性をつけることで、styleをそのコンポーネント内のみ適用することが可能(ローカルスタイル)。他のコンポーネントにスタイルを適用させたくない場合に使用する。scopedをつけなければ、全てのコンポーネントにスタイルが適用される(グローバルスタイル)。 |
Vuetifyで生成されたクラスのスタイルを修正
Vuetifyを使用していると、カスタマイズしてスタイルを修正したいケースがどうしてもでてきます。
そんなときは、Vuetifyで生成されたクラスのスタイルを直接修正します。
具体的には、開発者ツールを開いて、スタイルを修正したいクラスを探します。
今回のケースだと、v-toolbar__title
クラスを修正する必要があることが分かります。
overflow: hidden;
が適用されていることにより、文字が隠れてしまっているので、すべて表示させ、メニュー(HOME)とのスペースを少し空けたいため、以下のようにスタイルを定義します。
1 2 3 4 |
.v-toolbar__title { overflow: visible !important; margin-right: 50px !important; } |
また、確実にスタイルを適用させるために、Vuetifyで生成されたクラスのスタイルを修正する場合は、!important
をつけましょう。
これをつけなければ、スタイルが適用されないことがあります。
スタイルを上記のように修正して以下のように表示されればOKです。
グローバルなscssファイルをあらかじめ読み込ませる方法
ヘッダーメニューをレスポンシブ化する前に、今後共通的に使用するスタイルをグローバルscssファイルとして集約していきます。
「App.vue
へscopeを指定せずに定義すればよいのではないか」と思う方もいらっしゃるかもしれませんが、scss独自の記法等をしている場合、読み込みの順番等の影響によりうまく機能しない場合があります。
また、各コンポーネントに読み込ませる場合は、import文を毎回書かないといけないため、保守的によくありません。
したがって、今回はビルド時にあらかじめ共通的に使用するスタイルをグローバルscssファイルとして読み込ませるよう修正していきます。
ディレクトリ構成
まずは、srcフォルダ配下に以下のようなディレクトリおよびファイルを作成してください。
1 2 3 4 5 |
src ├── styles ├── common ├── _mixin.scss └── common.scss |
今回は、common.scss
に各共通スタイルを読み込ませるという設計にします。
_mixin.scss
こちらはPC・タブレット・スマホそれぞれの環境に応じてスタイルを適用させるためのメディアクエリファイルとなります。
各デバイスのブレークポイントはVuetifyのブレークポイントに合わせております。
以下のコードを貼り付けてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* メディアクエリブレークポイント */ $xs: 600; $sm: 960; $md: 1264; $lg: 1904; $sp-max: calc($xs - 1)px; $tb-min: $xs + px; $tb-max: calc($sm - 1)px; $pc-min: $sm + px; /* PC */ @mixin display_pc { @media (min-width: $pc-min) { @content; } } /* タブレット */ @mixin display_tab { @media (min-width: $tb-min) and (max-width: $tb-max) { @content; } } /* スマホ */ @mixin display_sp { @media (max-width: $sp-max) { @content; } } |
common.scss
各共通スタイルを読み込ませるファイルです。
今回は_mixin.scss
を読み込むため、以下のように記述します。
1 |
@import './_mixin.scss'; |
今後、各種共通スタイルファイルが追加となったら、このファイルに随時追加していきます。
vue.config.js
次にプロジェクト直下(package.json等がある階層)にvue.config.js
を作成します。
vue.config.js
はビルド時のオプションを定義するためのファイルとなります。
vue-cliがビルド時に自動で読み込んでくれます。
ただし、ファイル名は、必ずvue.config.js
である必要があります。
今回は、ビルド時にあらかじめグローバルなスタイルであるcommon.scss
を読み込むよう以下のようにコーディングします。
1 2 3 4 5 6 7 8 9 10 11 12 |
module.exports = { transpileDependencies: [ 'vuetify' ], css: { loaderOptions: { scss: { prependData: '@import "./src/styles/common/common.scss";' } } } } |
これでimport文を使用せずに共通スタイルを使用することができます。
レスポンシブなヘッダーメニューの作成方法
次に下図のようにスマホやタブレットのときはハンバーガーメニューを表示し、PCのときはナビゲーションメニューを表示するように修正していきます。
PCのときハンバーガーメニューを非表示にする
開発者ツールでハンバーガーメニュー全体をwrapしているクラスをみつけます。
すると、以下の赤枠のv-app-bar__nav-icon
クラスがハンバーガーメニュー全体をwrapしていることが分かります。
PCのとき、v-app-bar__nav-icon
クラスを非表示にするように、先ほど作成した_mixin.scss
のメディアクエリをinclude
して以下のようにコーディングします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<style lang="scss" scoped> .v-toolbar__title { overflow: visible !important; margin-right: 50px !important; } <!-- ここから追加 --> .v-app-bar__nav-icon { @include display_pc { display: none !important; } } <!-- ここまで追加 --> </style> |
画面の幅が960px以上のとき、ハンバーガーメニューが表示されなくなればOKです。
PCのときのみナビゲーションメニューを表示する
開発者ツールでナビゲーションメニュー全体をwrapしているクラスをみつけます。
すると、以下の赤枠のv-tabs
クラスがナビゲーションメニュー全体をwrapしていることが分かります。
デフォルトは非表示でPCのときのみv-tabs
クラスを表示するよう先ほどと同様メディアクエリを使用して以下のようにコーディングします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<style lang="scss" scoped> .v-toolbar__title { overflow: visible !important; margin-right: 50px !important; } .v-app-bar__nav-icon { @include display_pc { display: none !important; } } <!-- ここから追加 --> .v-tabs { display: none; @include display_pc { display: block !important; } } <!-- ここまで追加 --> </style> |
画面の幅が960px以上のときのみ、ナビゲーションメニューが表示されればOKです。
ヘッダーのコンポーネント化
これまでApp.vueにすべてコーディングしていましたが、このままだとApp.vueがどんどん大きくなり、ソースの可読性が悪くなるため、ヘッダーを別コンポーネントに切り出します。
ヘッダーコンポーネントの作成
src配下に以下のディレクトリおよびファイルを作成してください。
1 2 3 |
src ├── components ├── AppHeader.vue |
次に以下のように、App.vueファイルの内容を切り取り、AppHeader.vueファイルに貼り付けます。
作業内容
① header
タグ部分を切り取り、貼り付け
② script
タグ部分はディレクトリ構成が変わるので、import文のパス修正
③ script
タグにname
プロパティを追加し、コンポーネント名「AppHeader」を記述
④ style
タグ部分を切り取り、貼り付け
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<template> <header> <v-app-bar app dark > <v-app-bar-nav-icon @click="drawer = true"></v-app-bar-nav-icon> <v-toolbar-title>MyPortfolioSite</v-toolbar-title> <v-tabs> <v-tab v-for="(menuItem, index) in menuItems" :key="index" > {{ menuItem.name }} </v-tab> </v-tabs> </v-app-bar> <v-navigation-drawer v-model="drawer" absolute temporary > <v-list nav dense > <v-list-item-group> <v-list-item v-for="(menuItem, index) in menuItems" :key="index" > <v-list-item-title>{{ menuItem.name }}</v-list-item-title> </v-list-item> </v-list-item-group> </v-list> </v-navigation-drawer> </header> </template> <script> import constants from '../common/constants' export default { name: 'AppHeader', data () { return { drawer: false, menuItems: constants.menuItems } } } </script> <style lang="scss" scoped> .v-toolbar__title { overflow: visible !important; margin-right: 50px !important; } .v-app-bar__nav-icon { @include display_pc { display: none !important; } } .v-tabs { display: none; @include display_pc { display: block !important; } } </style> |
1 2 3 4 5 6 7 8 |
<template> <v-app> </v-app> </template> <script> </script> |
ヘッダーコンポーネントの読み込み
次に、先ほど作成したAppHeader.vueをApp.vueに読み込ませるために、App.vueを以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<template> <v-app> <AppHeader/> </v-app> </template> <script> import AppHeader from './components/AppHeader.vue' export default { name: 'App', components: { AppHeader } } </script> |
コンポーネントを読み込むためには、上記のように読み込み対象のコンポーネントをインポートして、components
プロパティを追加し、コンポーネントを定義する必要があります。
さいごに、動作確認をしてヘッダーをコンポーネント化する前と同じような挙動をすれば完了です。
今回はコンポーネント化のイメージをつかんでいただくために最後にコンポーネント化しましたが、次回以降はあらかじめコンポーネントを用意してから実装を進めていきます。
さいごに
以上でヘッダーのコーディングは完了です!
お疲れ様でした!
少し休憩して、次回はフッダーを実装していきましょう!
ES6について基礎から学習したい方は、以下の記事で紹介している教材がおすすめです。
VueJsの基礎知識についてより詳しく網羅的に学習したい方は、以下の記事で紹介している教材がおすすめです。
JavaScriptの基礎からVueJsが学べるスクールは以下の記事で紹介しております。
さいごまで読んでいただき、ありがとうございました。
知り合いから
「フリーランスエンジニアになれば、年収800万円以上の高報酬でかつ、自由な働き方をチョイスできる」
というのを聞いて、フリーランスエンジニアに興味を持ったのですが、
当時SIer企業でエンジニアをやっていたボクはなかなか一歩踏みだせませんでした。
というもの以下のような不安があったからです。
■フリーランスエンジニアってかなりの技術力がないとなれないのではないのか?
■フリーランスエンジニアって不安定なのではないのか?
■フリーランスエンジニアって人脈やコネ、営業力が必要なのではないのか?
しかし、実際にフリーランスエンジニアになってみて気づきました。
これらはすべて間違いです。
過去のボクのようにフリーランスエンジニアに興味あるけど一歩踏み出せないという方向けに
『フリーランスエンジニア転職完全ロードマップ』
という記事を書きました。
この記事読めば、どうすればフリーランスになれるのかが分かりますので、ぜひ一読ください。