【Vue.js】タグを props の値によって動的に生成する

  • Vue

Vue.js に限らず、Component に与えた props によって動的にタグを変更したい時があります。今回は Vue.js で見出し用の Heading コンポーネントを作成し、動的にタグ名をh1h2など変更できるようなコンポーネントを作成してみます。

export const Heading = {
  props: {
    // 見出しスタイルのレベル
    level: {
      type: Number,
      required: true
    },
    // タグ名
    tag: {
      type: String,
    },
  },
  computed: {
    tagName() {
      // tag が定義されていなければ h${level} の heading タグを出力する 
      return this.tag ?? `h${this.level}`
    },
    classes() {
      return {
        [`title--${this.level}`]: this.level,
      }
    }
  },
  template: `
    <component :is="tagName" class="title" :class="classes">
      <slot></slot>
    </component>
  `
};

:is プロパティに文字列を入れることで<component>が指定した文字列のタグに変換されます。

今回はタグとスタイルを分離して設定できるようにするため、以下のような props をもたせることにしました。また、何かしら拡張してclassesオブジェクトに他のクラスを動的追加することもできます。

  • level … 数値。それによって見出しレベルを変更する
  • tag … タグ名。もしない場合は、level に応じた <h○> タグになる

Vue では class に渡すオブジェクトの key 名が実際のクラスとして出力されるので、[]で囲むことで動的な class 名を与えるようにしています。

実際の使用例

level のみを指定

<heading :level="3">
  ...
</heading>
⇓
<h3 class="title title--3">
  ...
</h3>

level と tag 名も指定

<heading :level="2" tag="span">
  ...
</heading>
⇓
<span class="title title--2">
  ...
</span>

タグ名を変更するようなことは少ないと思いますが、念の為です。参考の記事で細かい解説が書かれています。