LoginSignup
9
6

More than 3 years have passed since last update.

Vue.jsでpropsとスタイルを動的に紐付けるやり方

Last updated at Posted at 2020-07-12

普段VuetifyIonicとったコンポーネントライブラリを使うのに慣れてるから、コンポーネント間のデータのやり取りやイベントは書ける。
けど、それをどうスタイルに紐付ければいいのか分からないってことありませんか?

<DemoButton color="primary" large icon outlined />

上記の

  • color
  • large
  • icon
  • outlined

っていう4つのpropsをどうスタイルに紐づけるか?
スタイルも意識したコンポーネントの作成をしてみましょう。

TL;DR

colorのようにを値の種類が複数あるものは style上書き
outlined のようにtrue/falseの真偽値で表せるものは class付与

コンポーネントの全体コード

動作環境としてはTypeScript化したNuxt.jsですが、概念を伝えるのが目的なので環境設定等は省略します。悪しからず。

DemoButton.vue
<template>
  <button type="button" :class="classes" :disabled="disabled" :style="styles">
    <slot></slot>
  </button>
</template>

<script lang="ts">
import Vue from "vue";
export default Vue.extend({
  name: "DemoButton",
  props: {
    color: {
      type: String,
      required: false,
      default: "primary"
    },
    disabled: {
      type: Boolean,
      required: false,
      default: false
    },
    outlined: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  computed: {
    styles () {
      //validateColorは @/assets/scss/_variable.scss で定義した色が指定されているかどうか確かめる為に作った関数
      return {
        '--color': validateColor(this.color),
      } 
    }, 
    // バインドするクラスを生成
    classes() {
      return {
        "demo-btn": true,
        "demo-btn--outlined": this.outlined
      };
    }
  }
});
</script>
<style lang="scss" scoped>
.demo-btn {
  // デフォルトの背景色
  --color: yellow;
  // CSS変数を背景色に割り当て
  background-color: var(--color);
}
.demo-btn--outlined {
  position: relative;
  display: inline-block;
  box-sizing: border-box;
  border: solid 1px;
  border-radius: 4px;
  background-color: transparent;
}
</style>

値のパターンをを複数もつprops

上記のコードで言うと color が該当します。
この引数は

  • primary
  • secondary
  • green
  • error

など様々な文字列を取る可能性があります。なのでこの場合は、
引数で指定された値を後からstyle属性で上書きする
という方法を使います。

.demo-btn {
  // デフォルトの背景色
  --color: yellow;
  // CSS変数を背景色に割り当て
  background-color: var(--color);
}

CSS変数でデフォルト値を設定しておき


<button type="button" :class="classes" :disabled="disabled" :style="styles">
styles () {
      /*validateColorは @/assets/scss/_variable.scss
                       で定義した色が指定されているかどうか確かめる為に作った関数*/
      return {
        '--color': validateColor(this.color),
      } 
    }

style属性に後から代入して上書きしています。

値が真偽値の2パターンしかないprops

こちらは簡単です。
引数が指定された場合のみそれに対応するクラスをコンポーネントに付与するだけです。

<button type="button" :class="classes" :disabled="disabled" :style="styles">
<script lang="ts">
props: {
    outlined: {
      type: Boolean,
      required: false,
      default: false
    }
classes() {
      return {
        "demo-btn": true,
        "demo-btn--outlined": this.outlined
      };
    }
</script>
<style lang="scss" scoped>
.demo-btn {
  // ...
}
.demo-btn--outlined {
  // ....
}
</style>

最後に

コンポーネントライブラリを作ってみよう!ってなっても、スタイルどうすればいいの?って人に少しでも参考になれば幸いです。

参考ページのリンクを貼っておきます

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6