11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue初級者がPropsとv-Slotをどう使い分けるかを考えた話

Last updated at Posted at 2019-12-18

#はじめに
Vue.jsをある程度やり、propsで子コンポーネントにデータの受け渡しをできるようになった…。
ところでSlotてあるけど、どういうシチュエーションで使っていくのだろうか、ってのを考えていきましょう。
ついでにPropsとどう使い分けていくのかも。
#おさらい
まずはPropsSlotは何なのかのおさらいをしていきましょう。
###Propsとは
Props - Vue.js

Vue.jsでコンポーネント間のデータの受け渡しをする上で最も基本的な機能ですね。
親側でv-bindや子側のProps名でデータを紐付けて、子側はProps内にプロパティで型とか状態を指定してって使い方。

parent.vue
<div>
  <child title="Qiita!"></child>
  <child :title="Vue"></child>
<div>
//*省略
data() {
  return {
    Vue: "Vue.js!"
  };
},
child.vue
props:{
  title:{
    type:String,
    required: true
  }
}

上のtitle="Qiita!"は文字列を受け渡し、下の:title="Vue"Vueというインスタンス変数などをv-bindで受け渡ししています。

###Slotとは
Slot - Vue.js

コンポーネントの開始タグと終了タグの間に、何かしらの要素があった時に、それを子側で<slot></slot>と置換する機能ですね。
子側に<slot></slot>がないと、親側でタグの間に要素があってもそれは表示されないので、表示させたい場合は子側に<slot></slot>を指定してあげる必要があります。

parent.vue
<template>
  <child>
    Qiita!
  </child>
</template>
child.vue
<template>
  <slot></slot>
</template>

<child>に囲まれた**Qiita!**の文字列が、子の<slot></slot>と置換され、**Qiita!**が表示されます。
なお、これは文字列だけではなく他のタグ要素に囲まれた物も置換されます。

parent.vue
<template>
  <child>
    <h1>Vue.js!</h1>
    <span>YES!Vue!</span>
  </child>
</template>
child.vue
<template>
  <slot></slot>
</template>

<h1>タグと<span>タグも、子の<slot></slot>と置換されます。
主に親コンポーネントの要素を子要素に差し込みたいってときに使うと思います。

#使い分けを考える
###値を渡すだけならProps
文字列なり数値なり、単にデータを受け渡すのならslotでやるよりもPropsでやるべきです。

###状態で中の要素が変わるならslot
v-ifなどで中の要素の構成が動的に変わる事があり、それを子側で挟み込んでやりたい。
という場合にはslotを使ったほうが、子側にpropsを使い状態を渡してやるよりも依存関係が薄くなり、
子側のコンポーネントの再利用性が上がるので、このような場合はslotを使いましょう。

parent.vue
<template>
  <child>
    <template v-if="flag">
      <h1>Vue.js!</h1>
      <span>YES!Vue!</span>
    </template>
    <template v-else>
      <p>Error!!!</p>
    </template>
  </child>
</template>
child.vue
<template>
  <slot></slot>
</template>

flagの値がtrueの時は上の要素が、falseの時は下のErrorとかかれた要素が表示されます。
また、置換したい親側の要素をVueコンポーネントにしても、それを子側のslotで置換することができます。

####AtomicDesignで使ってみよう

AtomicDesignを使ってコンポーネント設計を行っていた場合にでも、AtomMoleculesなど、コンポーネントの粒度が細かい箇所でよく使う機能になります。
特にAtomレベルのコンポーネントは、それ以上機能として分けれない、親との疎結合性を保つ必要がある、
などの必要があるのと、なによりもAtomコンポーネントの中に他の要素を入れる事はAtomicDesignの考えから離れてしまいます。
なので、AtomicDesignでも要素の子に別の要素を入れたい…!という時には、slotを使って置換させる、などの手法が特に有効と思います。

#おわり
作成中のプロジェクトでslotを使う機会が出てきたので、今回は記事にしてみました。
propsslotもどちらも子に何かしらの値や要素を受け渡す便利な機能ですが、
どちらも使い方によってはアンチパターンとなるので、しっかりとコンポーネントの設計を考えていく必要がありますね。

11
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
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?