🖌️

Vuetifyコンポーネントを柔軟にカスタマイズ!CSS変数とPropsの活用法

2025/01/27に公開

Vuetifyを使用した開発では、スタイリッシュなコンポーネントが手軽に利用できます。しかし、内部エレメントに直接スタイルを適用する際には制約があり、特定のカスタマイズが難しい場合があります。

この記事では、CSS変数とPropsを活用して、Vuetifyのコンポーネントを柔軟にカスタマイズする方法を解説します。

背景:Vuetifyのスタイル適用における課題

Vuetifyのコンポーネントは内部構造がカプセル化されており、通常のstyleclassバインディングだけでは特定のエレメントにスタイルを適用できない場合があります。

例えば、v-text-fieldコンポーネントの入力部分(v-field__input)にmin-heightmax-heightを指定したい場合、以下のようなコードでは反映されません。

<v-text-field :style="{ minHeight: '60px' }" />

この課題を解決するために、CSS変数と::v-deepを活用したカスタマイズが必要です。

解決策:CSS変数とPropsの活用

以下に、propsをCSS変数として内部エレメントに渡す具体的な実装例を示します。

実装例

custom-text-field.vue
<template>
  <v-text-field
    variant="outlined"
    :placeholder="placeholder"
    :style="computedStyles"
    density="compact"
  />
</template>

<script lang="ts" setup>
import { computed } from 'vue';

type Props = {
  placeholder?: string;
  minHeight?: string;
  maxHeight?: string;
};

// Propsの定義とデフォルト値の設定
const props = withDefaults(
  defineProps<Props>(),
  {
    minHeight: '48px', // デフォルト値
    maxHeight: '100%', // デフォルト値
  }
);

// Propsを使ってスタイルを動的に生成
const computedStyles = computed(() => {
  const styles: Record<string, string> = {};
  if (props.minHeight) styles['--custom-min-height'] = props.minHeight;
  if (props.maxHeight) styles['--custom-max-height'] = props.maxHeight;
  return styles;
});
</script>

<style scoped>
/* Vuetifyの深いカスタマイズには `::v-deep` を使用 */
::v-deep(.v-field__input) {
  min-height: var(--custom-min-height);
  max-height: var(--custom-max-height);
}
</style>

コードの解説

  • minHeightやmaxHeightをpropsとして定義し、外部から動的に値を渡せるようにします。
  • computedStylesで、propsの値をCSS変数(--custom-min-heightや--custom-max-height)に変換します。
  • これにより、CSS内で柔軟にスタイルを適用できます。
  • Vuetifyの内部エレメント(例: .v-field__input)はカプセル化されているため、::v-deepを使って直接スタイルを指定します。

実際に使ってみる

このコンポーネントを利用する際、以下のようにminHeightやmaxHeightを指定できます。

<CustomTextField placeholder="カスタムフィールド" minHeight="60px" maxHeight="120px" />

これにより、v-text-fieldの入力部分に高さの制約が適用され、柔軟なカスタマイズが可能になります。

なぜこの方法が最適なのか?

  • Vuetifyの内部構造を崩さない
    CSS変数を使うことで、Vuetifyが提供するコンポーネントのメリット(デザイン性・機能性)を維持できます。
  • 柔軟性
    propsを利用することで、コンポーネントの使い回しがしやすく、異なるデザイン要件にも対応できます。

まとめ

Vuetifyのコンポーネントを柔軟にカスタマイズするには、CSS変数や::v-deepを活用するのが効果的です。この方法を使えば、内部構造の制約を回避しつつ、必要なデザイン調整が可能になります。また、PropsとCSS変数を組み合わせることで、再利用性も高まります。ぜひ、これを活用してVuetifyの利便性を最大限引き出してください。

Discussion