Vue と Tailwind CSS でポートフォリオのようなものを作った

5 min読了の目安(約5300字TECH技術記事

作ったもの


画面
  • アイコン
  • 名前
  • 一言自己紹介
  • リンク
  • 作ったもの

を載せています。

Vue 3 と Tailwind CSS で作成し、GitHub pages で公開しています。
ヘッダーはZennのページを参考にしました。

得られた知見

以下は、得られた知見まとめです。他のやつはスクラップに書いてあります。

Tailwind CSS で max-h-5/6 を設定

Tailwind CSS では
max-h-5 (= max-height: 1.25rem;) や max-h-full (= max-height: 100%;)
はありますが、max-h-5/6 (= max-height: 83.333333%;) はありません。

Max-Height - Tailwind CSS に載っている通り、tailwind.config.jsに設定を加える必要があります。

以下は、デフォルトのmax-heightに加えて、max-height: 83.333333%;max-height-5/6と書いて使うための設定です。

tailwind.config.js
module.exports = {
  theme: {
    extend: {
      maxHeight: {
        '5/6': '83.333333%',
      },
    },
  },
}

定義されていない指定をすると狂うのでちゃんと確認し、無ければ自分で設定することが大事です。
h-hogeにはあってもmax-h-hogeは無いという例がいくつかあるので要注意。

Tailwind CSS で h-1/10 を設定

Tailwind CSS で h-1/10 (=height: 10%;) の-1/10ように、新しいspacingをデフォルトのspacingを維持して新しい設定を加えたい。
そんなときは、Customizing Spacingに載っている通り、同じくtailwind.config.jsextendに設定を加える必要があります。

tailwind.config.js
module.exports = {
  theme: {
    extend: {
      spacing: {
        '1/10': '10%',
      },
    },
  },
}

これでh-1/10だけではなく、w-1/10mx-1/10も使えるようになります。
Customizing Spacing

vim-swapを使うとTailwind CSSのクラス書く時便利

machakann/vim-swapiamcco/coc-tailwindcssのコマンドを使うと、class内の入れ替えに便利です。これは別の記事として書きました。

作ったものはyamlで管理

作ったものの欄を更新するときに、毎回Vueファイル等を書き換えるのは面倒です。そこで、作ったものの情報は別のファイルで管理することにしました(こういった管理は皆どうやってるんだろうか)。
jsonだとやたら長くなって見にくくなるため、以下のような形式のyamlにしました。

- name: Mr.Sagasu
  release_date: 2020/08/12-00:00
  description: ブックマークのみをアドレスバーで適当に検索できるChrome拡張機能
  here: https://chrome.google.com/webstore/detail/mrsagasu/kkendaacffjgfnjaolejgaopcoakacpb
  links:
    - title: github.com/eetann/mrsagasu
      url: https://github.com/eetann/mrsagasu
    - title: 使い方(Zennでの掲載)
      url: https://zenn.dev/eetann/articles/mrsagasu-introduction
    - title: 使い方(noteでの掲載)
      url: https://note.com/hideharu092/n/nf389a3d66d83
  tags:
  - Chrome拡張機能
  - JavaScript
  thumbnail: mrsagasu-thumbnail.jpg
  intro_img: mrsagasu_demo.gif

yamlの読み込みには、yaml-loaderを使いました。
Vueでの新しいloaderの追加方法は公式ドキュメントに書いてあります。

vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('yaml')
      .test(/\.ya?ml?$/)
      .use('json-loader')
      .loader('json-loader')
      .end()
      .use('yaml-loader')
      .loader('yaml-loader')
      .end()
  },
}

モーダルで詳しく表示

モダールはこちらを参考に作成しました。

最初は、作ったのもの名前をモーダルの一番上に表示していました。
名前が上に表示されているモーダル

しかし、名前が長い時の対処が面倒なことと、モーダルを開く前の表示と合わせるため、画像の下に名前を配置することにしました。以下が完成版です。
開く前と合わせたモーダル

Androidでは以下のような表示です。
Androidでのモーダル

"Links"の部分では、先程のyamlにlinksがあるかどうかをv-ifで判定して表示・非表示を決めています。
載せたいリンクは複数あるため、v-forを使って各リンクのtitleURLを表示しています。
これらのリンクはGitHubのレポジトリや使い方等の記事です。
記事のタイトルは、これから変更したり、モーダル内の他の情報と重複するものが多いため、 "使い方" のように簡素な表示にしました。

vueファイルの一部抜粋
<div v-if="work.links">
  Links
  <ul class="list-disc list-inside">
    <li v-for="link in work.links" v-bind:key="link.url">
      <a v-bind:href="link.url" class="underline">{{ link.title }}</a>
    </li>
  </ul>
</div>

また、この"Links"に表示するリンクの数によっては上記のモーダルの想定よりも長くなってしまうため、overflow-y-scroll(=overflow-y: scroll;)を使ってスクロールできるようにしています。
公式ドキュメント

"Here" の部分が配布先等のリンクですが、これで伝わるのかどうかちょっと悩んでいます。

で、ここからが一番詰まったところです。v-forの中の要素のうちの1つをクリックしたときに、そのクリックした要素に合わせてモーダル(MModalタグ)を表示しようとしました。
最初は以下のように書いていました。

だめな例
<template>
  <div
    v-for="work in works"
    v-bind:key="work.release_date"
  >
    <MModal v-if="showModal"></MModal>
  </div>
</template>

これだと、v-forで回っている要素すべて(ここではモーダル)が同時に表示・非表示になってしまいます。v-forの中の要素ごとに表示・非表示を切り替えるために、v-ifではそれぞれ固有の値で判断する必要があります。
ここでは、そのままkeyを使ってv-if="showModal == work.release_date"としました。

最終的なソースコードはこちら

最後に

Vue と Tailwind CSS を使い始めたばかりなので、最適な書き方かどうかまだ分かっていません。
しかし、それなりのポートフォリオができたと思います。これからも公式のドキュメント読みつつ改善していこうと思います。
Tailwind CSSVue 3Vue CLI のドキュメントはとても検索しやすいです。

結論:公式のドキュメントは強い。