はじめに

今回はVue、Typescript、CSS設計のBEMとの組み合わせでクラスを複数書き分けれられるようにしているメモ。

Vueのクラスへは配列にして渡すことで複数のクラスを動的に付与できるようになっている

ボタンコンポーネントの例

下記のようにしてクラスをかき分ける。ゲッターを使って算出プロパティでPropsの値を監視し、それをcustomClassでそれぞれの値の変化を検出して、配列にし、コンポーネントへ割り当てる。

Button.vue
<template>
  <button type="button" :class="customClass">
    <slot />
  </button>
</template>

<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";

@Component({
  name: "Button"
})
export default class Button extends Vue {
  private defaultClassName = "btn";
  @Prop({ default: "" }) private color!: string;
  @Prop({ default: false }) private round!: boolean;
  @Prop({ default: "" }) private fontSize!: string;

  get colorClass() {
    return this.color ? `${this.defaultClassName}--${this.color}` : "";
  }

  get roundClass() {
    return this.round ? `${this.defaultClassName}--round` : "";
  }

  get fontSizeClass() {
    return this.fontSize
      ? `${this.defaultClassName}--font-${this.fontSize}`
      : "";
  }

  get customClass() {
    return [
      this.defaultClassName,
      this.colorClass,
      this.roundClass,
      this.fontSizeClass
    ];
  }
}
</script>

<style lang="scss" scoped>
.btn {
  display: block;
  width: 100%;
  border-width: 1px;
  border-style: solid;
  color: #fff;
  text-align: center;
  font-size: 14px;
  font-weight: bold;
  padding: 12px 5px;
  line-height: 1;
  &--white {
    color: #707070;
    background-color: #ffffff;
    border-color: #ffffff;
  }
  &--orange {
    background-color: #f5ab45;
    border-color: #f5ab45;
  }
  &--font-large {
    font-size: 16px;
  }
  &--font-small {
    font-size: 12px;
  }
  &--round {
    border-radius: 5px;
  }
}
</style>

そうすると親コンポーネントでは以下のようにして利用することができる

Parent.vue
<template>
  <Button color="orange" font-size="large" round>
    ボタン
  </Button>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import Button from "@/components/atoms/Button.vue";

@Component({
  name: "Parent",
  components: { Button }
})
export default class Parent extends Vue {}
</script>

まとめ

これで自由にクラスを複数付与するコンポーネントを作ることができる。