Help us understand the problem. What is going on with this article?

Vue、TypescriptでDomのClassを配列にし、動的に変化させたコンポーネントを作る

More than 1 year has passed since last update.

はじめに

今回は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>

まとめ

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

MikihiroSaito
Javascript好きな人。将来ボホール在住エンジニア。 技術関連の記事をメインに情報を発信します。 Tyepscript、React、Vue(Nuxt)、Git、Docker等
https://blog.boholabo.com
yyphp
PHPerが毎週集まり、ざっくばらんに情報交換する雑談コミュニティ
https://yyphp.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away