LoginSignup
1
2

More than 3 years have passed since last update.

Vue.jsのスロットを理解する!

Posted at

プロジェクトの作成

今回はvue cliををつかっていきます。

vue create プロジェクト名

App.vue を書き換えていきます。

App.vue
<template>
<div>
  <h1>スロットを学んでいきます</h1>
  <hr>
  <Test name="阿部" message="よろしくお願いいたします。"></Test>
</div>
</template>

<script>
import Test from "../src/components/Test"
export default {
  components: {
    Test,
  }
}
</script>

<style>
hr {
  border: 1px solid red;
}
</style>

コンポーネントを一つ作成します。

src/components/Test.vue
<template>
  <div>
    <h1>名前は{{name}}です</h1>
    <p>{{message}}</p>
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true,
    },
    message: {
      type: String,
      required: true,
    },
  },
}
</script>

スクリーンショット 2021-03-22 18.08.39.png

現在は純粋にpropsを受け取っている状態になります。

スロットとは?

親から子にデータを渡す際にHTMLのタグのデータまで同時に渡すことができます。
実際にやってみた方が早そうなのでやってみます

App.vue
 <Test name="阿部" message="よろしくお願いいたします。">
    <hr>
    <h1>こちらスロットです</h1>
 </Test>

App.vueの部分を書き換えてみましょう

Test.vue
<template>
  <div>
    <h1>名前は{{name}}です</h1>
    <p>{{message}}</p>
    <slot></slot>
  </div>
</template>

Testコンポーネント部分にslotタグを設置します。
スクリーンショット 2021-03-22 18.12.15.png

こうなります。
つまり親の コンポーネントの間に記述したHTMLの内容がslotで受け取れているのがわかると思います。

App.vue
<template>
<div>
  <h1>スロットを学んでいきます</h1>
  <hr>
  <Test name="阿部" message="よろしくお願いいたします。">
    <hr>
    <h1>{{slotMessage}}</h1>
  </Test>
</div>
</template>

<script>
import Test from "../src/components/Test"
export default {
  components: {
    Test,
  },
  data() {
    return {
      slotMessage: "スロットのメッセージです"
    }
  }
}
</script>

このようにデータプロパティを追加して子にデータを渡すことも可能になります。

デフォルトのスロット

<slot>デフォルトのスロット</slot>

スロットはスロットタグの中にデフォルトのスロットを設定することができます。
これはコンポーネント内のデータがない場合のみ、デフォルトのスロットが適用され、ある場合はデフォルトのスロットは打ち消されます。

名前つきスロット

<slot></slot>
<slot></slot>
<slot></slot>

複数スロットっておけるの?
結論から言うとできます。

スクリーンショット 2021-03-22 18.22.11.png
純粋に3つおくとスロットが3つ描画されます。

ではこのスロットをそれぞれ違う文字を描画していきたい場合、使うのが名前付きスロットです!

App.vueを書き換えましょう

App.vue
<template>
<div>
  <h1>スロットを学んでいきます</h1>
  <hr>
  <Test name="阿部" message="よろしくお願いいたします。">
    <hr>
    <template v-slot:first>        
      <p>一つ目のスロット</p>
    </template>
    <template v-slot:second>        
      <p>二つ目のスロット</p>
    </template>
    <template v-slot:third>        
      <p>三つ目のスロット</p>
    </template>
  </Test>
</div>
</template>

<script>
import Test from "../src/components/Test"
export default {
  components: {
    Test,
  },
}
</script>

<style>
hr {
  border: 1px solid red;
}
</style>
Test.vue
<template>
  <div>
    <h1>名前は{{name}}です</h1>
    <p>{{message}}</p>
    <slot name="first"></slot>
    <slot name="second"></slot>
    <slot name="third"></slot>
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true,
    },
    message: {
      type: String,
      required: true,
    },
  },
}
</script>

説明するとまずまずtemplateタグで囲みv-slotディレクティブを設定します(こちらは好きな値を追加しましょう)
受け取る側はname属性で指定した値を受け取ります。
これで言うと

//これで送信
<template v-slot:first>
最初のスロット
</template>

//これで受け取り
<template name="first">

ってイメージです!
ここは必ずtemplateタグを使う必要がありv-slotとtemplateはセットだと思ってください。
ちなみにこの名前付きスロットはバージョン2.6.0以上で対応しています!

省略記法

v-slotは#に省略することができます。

v-slot:title  ===  #title

って感じです。

お疲れさまでした!!

1
2
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
1
2