18
10

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.

【Nuxt.js】slot基礎編:コンポーネントの一部を置き換えよう

Last updated at Posted at 2019-12-18

前置き

Nuxt.jsと言えばコンポーネント。
componentの内容を、ページによって少しで良いから変えたい…
そんな時、slotに随分と助けられたので記録に残しました。
Vue.jsでも同様の使い方が可能です。
※サンプルテキストはHello Nuxt.js!ではなくHello Vue.js!になっていますが、ご了承ください。

間違い等がございましたら、優しくご指摘いただけると嬉しいです!

基礎編:超簡単な解説から実践編まで
応用編:全体のまとめ、propsとの違い
を書いていきます。

slotって?メリットは?

ウェブサイトを作ってて、
「同じコードをコピペしまくってめんどいなぁ〜
 あ!コンポーネント使えばいいじゃん!!
 あれ?でもページによって○○だけ変えたいんだよなぁ」
って時、ありますよね?

コンポーネントを使いまわしたいけど、
ここの文字だけ変えたい!って時に使います。
(文字以外も変更は利きますが、今回はわかりやすく文字で例えます)

コンポーネントが使えないから、
基本のコードコピペして中身だけ編集する…
なんて面倒なことをしなくていいんです!
コンポーネントにしちゃって、一部だけ変えればいいんです!
楽ちん!!

slotを使わない場合どうなるの?

じゃあコンポーネントを使って…親コンポーネントで中身を変えよう!
slotなくてもの中身に書けばよくない?
と思ったそこのアナタ!
こちらをご覧ください。

Component.vue
Component.vue // 子コンポーネント
<div class="ItemTitle">
 <h1>ここは親ページによってタイトルを変えたい</h1>
</div>
index.vue
index.vue // 親ページ
<Component>
 Hello Vue.js!
</Component>
表示結果
<div class="ItemTitle">

</div>

そうなんです。。。
子のコンポーネントの中身は無視されちゃいます。
それも完全なシカトです。ツライ。。。

<Component>ここは無視される</Component>

slotの使い方(超簡単ver.)

そこでslot君の登場です!!
使い方は超〜〜〜簡単。
子コンポーネント内に変えたい部分をslotにするだけ。
上の説明に使ったコードでやってみます。

【表示結果】
picture_pc_96a0996a6f584fe201bfcad0b23a9059.png

<div class="itemTitle">
 <h1>Hello Vue.js!</h1>
</div>

【コード】

子コンポーネントだけslotを加えます。

Component.vue
Component.vue // 子コンポーネント
<div class="itemTitle">
 <h1>
  <slot /> // ここは親ページによってタイトルを変えたい
 </h1> 
</div>

<style scoped>
.itemTitle {
 margin: 10px;
}
h1 {
 color: rgb(65, 193, 222);
}
</style>

親は一緒。

index.vue
index.vue // 親ページ
<Component>
 Hello Vue.js!
</Component>

これだけで表示結果が変わる!!
slotくんに呼びかけて、ちゃんとデータを表示してくれます。
偉いぞslotくん!!!

slotの使い方(複数ver.)

便利なslotくん
「じゃあいっぱいslot使おう!
 h1とh2にも使おう〜」
って場合は
各slotに名前をつけてあげる必要があります。

「これ表示して?」って言われても、
名前で呼んでくれないと、
どのslotくんが表示すればいいのか分からなくなっちゃいますよね。

そういう先輩いません?
「これやっといて〜」って、
今誰に言ったの?私やるの???え、誰???
みたいな。

なので、
もし名前をつけないでslotを2つ用意すると
親に入れたものが2回表示されます。
「はいはい、私やりますね」って2人反応しちゃいます。

名前で呼ばなかった先輩はきっと
同じ仕事を無駄に2個やらせてしまったことを後悔するでしょう。
こんなにいらんわ。。。って。

【表示結果】
picture_pc_cd512416e11b9b6b113ed8fa8676b625.png

<div class="ItemTitle">
 <h1>
  Hellot Vue.js!
  about slot
 </h1>
 <h2>
  Hellot Vue.js!
  about slot
 </h2>
</div>

【コード】

Component.vue
Component.vue // 子コンポーネント
<div class="ItemTitle">
 <h1>
  <slot /> // ここは親ページによってタイトルを変えたい
 </h1>
 <h2>
  <slot /> // ここは親ページによってサブタイトルを変えたい
 </h2>
</div>

<style scoped>
.itemTitle {
 margin: 10px;
}
h1 {
 color: rgb(65, 193, 222);
}
h2 {
 color: gray;
}
</style>
index.vue
index.vue // 親ページ
<Component>
 Hellot Vue.js!
 about slot
</Component>
表示結果
<div class="ItemTitle">
 <h1>
  Hellot Vue.js!
  about slot
 </h1>
 <h2>
  Hellot Vue.js!
  about slot
 </h2>
</div>

slotの使い方(実践ver.)

ということで各slotくんに名前をつけてあげましょう。
「◯◯くん、これ表示しといてよ」って言ってくれたら、
はい、私ですね!表示しますね!ってなりますよね。

ここで1つ注意。
名前をつける場合は、
親でタグで囲う必要があります。
これさえできればもう完璧。

【表示結果】
picture_pc_912dbfccaa95a0ce68d99cf19a889283.png

<div class="itemTitle">
 <h1 class="title">Hello Vue.js!</h1>
 <p>slotを学ぼう</p>
 <div class="catchCopy"># slotって?メリットは?</div>
</div>

【コード】

ItemTitle.vue

ItemTitle.vue // 子コンポーネント
<div class="itemTitle">
 <h1>
  <slot name="title" /> // 置き換えたい部分のslot nameを決める
 </h1>
 <p>slotを学ぼう</p> 
 <h2>
  <slot name="catchCopy" /> // 置き換えたい部分のslot nameを決める
 </h2>
</div>

<style scoped>
.itemTitle {
 margin: 10px;
}
h1 {
 color: rgb(65, 193, 222);
}
p {
 color: gray;
h2 {
 color: rgb(76, 212, 227);
}
</style>
index.vue
index.vue // 親ページ
<ItemTitle>
 <template v-slot:title>
  Hello Vue.js! // slot name="title"を置き換える
 </template>
 <template v-slot:catchCopy>
  # slotって?メリットは? // slot name="catchCopy"を置き換える
 </template>
</ItemTitle>

おめでとうございます!
これでVue.js、Nuxt.jsのslot、今日から使えますね!わーい!
次は更なる応用も記載していきます★

18
10
1

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
18
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?