「VuetifyでQiita風のコンポーネントを作る」、今回はヘッダーのチーム切り替えメニュー編です。
目的やVuetifyの説明、他のコンポーネントについてはこちら
チーム切り替えメニューとは
ロゴの右側にある、下三角から開けるメニューのことです。(命名は勝手にしました。)
Qiita:Teamに所属していない方にはあまり馴染みのないものかもしれませんが、
Qiita:Teamにログインしていると、このメニューから切り替えることができます。
実際のイメージはこのような感じです。
Vuetifyで実装
まずはCodepenで作ったサンプルを紹介。
See the Pen Vuetify Qiita風Team切り替えメニュー by totto357 (@totto357) on CodePen.
SFCで表現するとこちら。
<template lang="pug">
// チーム切り替えメニュー
v-menu(offset-y nudge-bottom="16px")
// activator
v-sheet.mr-2(slot="activator" color="green darken-2")
v-icon arrow_drop_down
// 別のチームにログインしている
v-card(v-if="isLoginToTeam" width="300px")
v-list(dense)
v-subheader ログイン中のチーム
template(v-for="team, i in teams")
v-divider.my-1(v-if="i!=0" inset)
v-list-tile(avatar @click="" :key="team.name")
v-list-tile-action
v-icon(v-if="team.view") mdi-check
v-list-tile-content
v-list-tile-title {{ team.name }}
v-spacer
v-layout(align-center justify-end)
v-avatar(size="20px")
v-img(:src="team.user.img")
span.ml-1 {{ team.user.name }}
v-divider.my-1
v-list-tile(avatar @click="")
v-list-tile-action
v-icon mdi-exit-to-app
v-list-tile-content
v-list-tile-title 別のチームにログイン...
// 別のチームにログインしていない
v-card(v-else width="250px")
v-list(dense)
v-list-tile(avatar @click="" )
v-list-tile-action
v-icon mdi-check
v-list-tile-content
v-list-tile-title Qiita
v-divider.my-1
v-subheader ログイン中のチームがありません
v-list-tile(avatar @click="")
v-list-tile-action
v-icon mdi-exit-to-app
v-list-tile-content
v-list-tile-title Qiita:Team にログイン...
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
data: () => ({
isLoginToTeam: true,
teams: [
{ view: false, name: "HogeTeam", user: { name: "totto357", img: "https://qiita-image-store.s3.amazonaws.com/0/97227/profile-images/1516012241" }},
{ view: true, name: "Qiita", user: { name: "totto357", img: "https://qiita-image-store.s3.amazonaws.com/0/97227/profile-images/1516012241" }},
],
}),
})
</script>
Tips
-
v-menu
やv-dialog
などを表示する際のトリガーとなるボタンやテキストは、activator
というスロットを通して表現することができる -
offset-y
、nudge-bottom
でヘッダーの下部とメニューの上部が揃うように位置調整 -
v-sheet
は高さと幅を自由に設定できるので、わりと重宝する-
v-card
のベースにもなってるコンポーネント - 公式のサンプルはあまりないけど、自由度が高いので好きに使える
-
- Qiita:Teamでログインしているかどうかの切り替えは
v-if
を使って切り替えを行う - 区切り線として利用する
v-divider
はinset
というプロパティで幅を調整することができる -
v-list-tile-action
の幅が広すぎると感じたら無理に使わなくてもよい -
v-icon
はFont AwesomeとMaterial Design Icons
使えるので、Material Iconsに合うものがなければ探してみるといいかも
v-menu
でよく使うプロパティ
今回のようにVuetifyでメニューを表示するのに利用するv-menu
ですが、いろんなプロパティを設定することができます。
その中でも自分がよく使うプロパティを紹介したいと思います。
close-delay
メニューが閉じるまでの時間を制御することができます。
基本的には後述するopen-on-hover
と利用することが多いかも。
例えば、ホバーで開くメニューがあって、デザイン上activator
とメニューをちょっと離している場合、
activator
からメニューにカーソルを移動するとホバーが外れてしまうのでメニュー閉じてしまうことがあります。
そんな時に、メニューが閉じるまでのディレイを設定することでメニューが閉じないように制御することができます。
close-on-content-click
メニューのコンテンツ部分(デフォルトスロットで渡したコンポーネント)をクリックしたときにメニューを閉じるかどうかを制御できます。
リンクしかないメニューであれば問題ないですが、何かを入力してもらいたいようなメニューだとクリックで閉じてしまうと困ります。
そんなときにclose-on-content-click
をfalse
に設定すると、クリックしてもメニューが開いたままになります。
デフォルトはtrue
なので、クリックしても閉じるようになっています。
nudget-系
activator
に対してメニューの位置をどの程度ずらすのか設定することができます。
例えばnudge-bottom
であれば、メニューを表示する起点から下方向にどれだけずらすのかを指定できます。
(起点はデフォルトではactivator
の左上。後述のoffset-系
で変更できる。)
今回の「チーム切り替えメニュー」ではヘッダーの下部とメニューの上部を合わせたかったので、
nudge-bottom
に16px
を指定しています。
offset-x, offset-y
メニューを表示する起点を変更することができます。
offset-x
を指定すると、x軸の起点がactivator
の左から右に変更されます。
offset-y
を指定すると、y軸の起点がactivator
の上から下に変更されます。
つまり、まとめると以下となります。
- なし: 左上
- offset-xのみ: 右上
- offset-yのみ: 左下
- 両方: 右下
open-on-hover
カーソルをactivator
にホバーさせるだけで、メニューを開くかどうかを制御できます。
close-delay
でも書きましたが、nudge-系
を使ってるときにはカーソル移動でメニューが消えてしまうことがあるので、注意が必要です。