ContractS開発者ブログ

契約マネジメントシステム「ContractS CLM」の開発者ブログです。株式会社HolmesはContractS株式会社に社名変更しました。

【Vue.js】Painless なコンポーネント開発のプラクティス

はじめに

こんにちは!ContractS株式会社の北原です。
フロントエンドのリードとして、プロジェクトの技術選定や品質保守等を担当しています。

早速ですが...

みなさまは Vue 3 をお使いになられていますか?
これには、以前の Vue 2 と比較して多種多様な改善がふんだんに盛り込まれています。
2020/09/18 にリリースされてから暫く経っているので、実際の業務や個人で触られた方も多いと思います。

例えば、

  • Composition API の正式採用
  • script setup 構文の対応
  • メモリ使用量削減による負荷軽減

その他色々ありますが、以上のような機能により、従来のメジャーバージョンからご利用になっていた開発者からすると嬉しいものが満載です。

しかし、ただひとつ。 頭を悩ませる要素があるのです。
それこそが本稿を作ったきっかけです。

:deep 機能について

Vue 3 には:deepという擬似クラスとして利用できる機能があります。
これは、コンポーネントから、子コンポーネントの特定要素に対してスタイルを当てたい時に避けては通れない道です。

:deep の具体的な使い方については、以下の公式ドキュメントをご覧ください
ja.vuejs.org

:deep 機能のつらいところ

Atomic Design程やらないまでも、多くのデザインシステムではatomsのように基底コンポーネントを作成し、各コンポーネントで使う形だと思います。

自社で全ての基底コンポーネントをスクラッチで作成し利用すれば、SFC で運用しても自由にスタイルをカスタマイズできるので問題ないですが、多くのプロジェクトでは VuetifyQuasar のようなUIライブラリをご利用になると思います。

また、そのままの見た目で利用することは少なく、UX統一等の理由でスタイルを適用すると思います。
当然ライブラリなので、日々バージョンアップが行なわれていきます。その際にコンポーネントのDOM構造が変化することもあるでしょう。

:deepは前述の通り擬似クラスであり、CSSセレクタである以上、UIライブラリのコンポーネントのDOMを知らないといけません。
方法としては様々あると思いますが、検証ツール等を用いてスタイルを当てたい要素を探し、その要素を一意に特定できるセレクタを作ってスタイルを当てる必要があります。

これを頻繁にメンテナンスするのは高コストで、コンポーネントに新規のバリエーションを持たせたい時にもスピーディな開発を阻害します。

そんなあなたに PrimeVue

PrimeVue は、Vue 3 で利用可能なUIライブラリのひとつであり、90をも超える多彩なコンポーネントと堅牢なFWを提供しています。
今回紹介する機能を抜きにしても、単品として高いアクセシビリティを誇るので、是非以下で触ってみてください。

primevue.org

PrimeVue の Pass Through 機能

Pass Through (パススルー) 機能は、ドキュメントで以下のように説明されています。

The Pass Through props is an API to access the internal DOM Structure of the components.

要するに、このAPIを利用することでPrimeVueのコンポーネント内部のDOM構造へアクセスが可能になるというわけです。
すでに:deepで感じていた pain を解決できる匂いがしますね。

Pass Through の利用方法

PrimeVueで提供される全てのコンポーネントには、ptという名称のpropsが用意されています。
そこに、PrimeVueのDOM毎の命名をkeyとして持つObjectをbindすることで、DOMのカスタマイズが可能です。

これだけだと分かりづらいと思うので、今回は Vue Button Component を具体例として挙げます。

ご覧いただくと、PASS THROUGHタブ内で、画像のようにDOM毎に連番が割振られていると思います。

PrimeVue Button の Pass Through 連番

ここで、4番のラベル部分のスタイルをカスタマイズしたいとします。
そのまま下にスクロールしていただくと、対象の連番に対して命名があると思います。

PrimeVue Button の Pass Through 命名

labelという命名がなされていますね。
これをkeyとした Object を、SFC上で以下のようにbindします。

PrimeVue Button の Pass Through Bind

Tailwind CSS のクラスであるfont-boldを適用してみました。

なんとこれだけで、PrimeVue Button のDOM構造を知らずともスタイルが適用できてしまいます。
画像のようにcomputedを bind することで動的なスタイル変更も可能です。
今回はTailwind CSSを利用しましたが、グローバルなUtility Classとも非常に相性がいいです。

最後に

いかがでしたでしょうか?

:deepで大変な目に遭われた、もしくは今まさに遭われている方もいらっしゃるかと思います。私も同じで、Nuxt 2からNuxt 3へマイグレーションを行なう際にとても痛い目を見ています...笑

もし良さそう!と感じていただけましたら、導入は以下で簡単に行なえますので、是非お試しください!

出典

グループ会社間で行なった勉強会の内容となります。
本稿よりも、もう少し実際の利用例や他機能も交えた解説を行なっていますので、よろしければご覧ください!