こんにちは。
Vue.jsやReactが流行っていることもあり、つい最近Vue.jsについて学び始めました。(まだ触れてみたくらい?)
Vue.jsに触れてみて何かに活用してみたいなと思ったので、ドロワーメニューに活用したものを学習ログとしてここに残そうと思います。
ドロワーメニューの完成版
簡易ではありますが、Vue.jsを使って下記gifのようなドロワーメニューを作ってみました。
Vue.jsを使って書いた完成版のコードは下記になります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ドロワーメニュー</title>
<link rel="stylesheet" href="style.css">
<script src="https://unpkg.com/vue@next"></script>
<script src="app.js" defer></script>
<script src="script.js" defer></script>
</head>
<body>
<div id="app">
<nav class="header__nav" :class="{'is-drawerActive' : isActive}">
<h2 class="visuallyHidden">サイト内メニュー</h2>
<button type="button" class="hamburger" aria-controls="globalNav" :aria-expanded="isActive" @click="drawer">Menu</button>
<ul id="globalNav" class="globalNav">
<li v-for="i in 5">メニュー{{ i }}</li>
</ul>
</nav>
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
}
body {
padding: 5rem;
background-color: #fff;
}
.visuallyHidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0 0 0 0);
border: 0;
white-space: nowrap;
clip-path: inset(50%);
}
.globalNav {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
padding: 5rem;
background-color: #212121;
color: #fff;
transition: transform .3s ease-in-out;
transform: translate3d(100%, 0 , 0);
}
.is-drawerActive .globalNav {
transform: translate3d(0, 0 , 0);
}
.hamburger {
position: fixed;
top: 3rem;
right: 3rem;
z-index: 2;
width: 5rem;
height: 5rem;
border-radius: 50%;
background-color: transparent;
border: 1px solid currentColor;
mix-blend-mode: exclusion;
color: #fff;
cursor: pointer;
appearance: none;
}
Vue.createApp({
data() {
return {
isActive: false,
};
},
methods: {
drawer() {
this.isActive = !this.isActive;
}
}
}).mount("#app");
Vue.jsを使ったドロワーメニューの作り方
Vue.jsを使ったドロワーメニューの作り方について下記に記載していきます。
基本的なHTML
Vueを使用するためにはインストールをする必要がありますが、今回はCDNを利用しているため、headタグ内に下記コードを記載します。
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
CDNを読み込んだ後は、基本的なHTMLとJSファイル内にVueのインスタンスを作成していきます。
今回はVueで操作していきたい要素に「app」というid名に付けています。
<body>
<div id="app">
<nav class="header__nav">
<h2 class="visuallyHidden">サイト内メニュー</h2>
<button type="button" class="hamburger" aria-controls="globalNav" aria-expanded="false">Menu</button>
<ul id="globalNav" class="globalNav">
<li>メニュー1</li>
<li>メニュー2</li>
<li>メニュー3</li>
<li>メニュー4</li>
<li>メニュー5</li>
</ul>
</nav>
</div>
</body>
Vue.createApp({
data() {
return {
};
},
}).mount("#app");
Vueのディレクティブを使ってメニューを書き換える
基本的なHTMLを書いた後は、Vueの「v-for」ディレクティブを使って繰り返し処理をしていきます。
下記の書き方をすることによって、メニュー1〜メニュー5までを画面上に映し出すことができます。
<li v-for="i in 5">メニュー{{ i }}</li>
「v-for」を用いてメニューを書き換えたHTMLが下記になります。
<body>
<div id="app">
<nav class="header__nav">
<h2 class="visuallyHidden">サイト内メニュー</h2>
<button type="button" class="hamburger" aria-controls="globalNav" aria-expanded="false">Menu</button>
<ul id="globalNav" class="globalNav">
<li v-for="i in 5">メニュー{{ i }}</li>
</ul>
</nav>
</div>
</body>
メソッドを使ってドロワーメニュを表示/非表示にする
「is-drawerActive」クラスが付与されるとメニューが出てくる仕様なため、「v-on」と「v-bind」ディレクティブ、さらにメソッドを使ってclassの付け外しが出来るようにしていきます。
buttonタグをクリックしたときに「is-drawerActive」クラスの付け外しが出来るようにしたいため、buttonタグに「v-on」ディレクティブを、navタグに「v-bind」ディレクティブを付け加えます。
<div id="app">
<nav class="header__nav" :class="{'is-drawerActive' : isActive}">
<h2 class="visuallyHidden">サイト内メニュー</h2>
<button type="button" class="hamburger" aria-controls="globalNav" :aria-expanded="isActive" @click="drawer">
Menu
</button>
<ul id="globalNav" class="globalNav">
<li v-for="i in 5">メニュー{{ i }}</li>
</ul>
</nav>
</div>
また、JSファイルにメソッドを定義していきます。
Vue.createApp({
data() {
return {
isActive: false,
};
},
methods: {
drawer() {
this.isActive = !this.isActive;
}
}
}).mount("#app");
dataプロパティ内にてisActiveの値をfalseに定義しておき、drawerメソッドでfalseとtrueが切り替わるようにしています。
そのため、属性を操る「v-bind」を用いることで、「isActive」がtrueの時に「is-drawerActive」クラスが付与され、falseの時には「is-drawerActive」クラスが外されます。
ちなみにですが、「v-on」と「v-bind」は省略記法を用いています。
「v-on」:イベントを指定する
<button v-on:click="drawer">Menu</button>
<!-- 省略記法 -->
<button @click="drawer">Menu</button>
「v-bind」:属性を操作する
<nav class="header__nav" v-bind:class="{'is-drawerActive' : isActive}">
<!-- 省略記法 -->
<nav class="header__nav" :class="{'is-drawerActive' : isActive}">
終わりに
Vue.jsを使えば、JavaScriptよりも少ない記述量でドロワーメニューを動かせることがわかりました。
もっと応用できるようにVue.jsを学びたいと思うと同時に、JavaScriptの理解も深めていきたいと思います。