はじめに
vueを学習していてスコープ付きスロットとはなんなのか?なぜこれが必要なのか?という疑問が解消したのでまとめます。スロットという概念を理解されている方を想定しています。
スロット
まずはApp.vue(親)とMyBook.vue(子)を用意します。今回は子コンポーネントで定義しているデータ(Book,Userに関する情報)を親コンポーネントの方で利用してみたいと思います。
<MyBook>
<template v-slot:default>
{{book.title}} ({{book.price}}円)<br>
購入者:{{ user.name }}
</template>
</MyBook>
<template>
<div>
<slot name='default'>{{book.title}} ({{book.publish}})</slot>
</div>
</template>
<script>
export default {
data: function() {
return {
book: {
title: 'これからはじめるvue.js実践入門 ',
price: 3000,
publish: 'SBクリエイティブ'
},
user: {
name: 'sin-sudo',
age: 20,
gender: 'male'
}
}
}
}
</script>
このコードで期待するのはデフォルトで設定されている、本のタイトル:出版社名を親コンポーネントの方で本のタイトル:本の値段で置き換えるというものです。
画面的にはこのようになると思い通りに動作しているということになるのですが、今の状態でブラウザを確認してみると、
こんな感じのエラーがたくさん出て怒られてしまいますね。
これは親コンポーネントでのデータは親コンポーネントが、子コンポーネントのデータは子コンポーネントが管理するというvueの思想があるからなんですね。
親コンポーネントのテンプレートは親コンポーネントの管理下にあるので基本的に親から子のデータにアクセスすることはできません。ここで利用するのがスコープ付きスロットです。これを使うことで子コンポーネントのデータにアクセスすることができるようになります。
先ほどのファイルを以下のように編集します。
<MyBook>
<template v-slot:default='slotProp'>
{{slotProp.book.title}} ({{slotProp.book.price}}円)<br>
購入者:{{ slotProp.user.name}}
</template>
</MyBook>
<template>
<div>
<slot name='default' v-bind:book = 'book' :user = 'user'>{{book.title}} ({{book.publish}})</slot>
</div>
</template>
<script>
export default {
data: function() {
return {
book: {
title: 'これからはじめるvue.js実践入門',
price: 3000,
publish: 'SBクリエイティブ'
},
user: {
name: 'sin-sudo',
age: 20,
gender: 'male'
}
}
}
}
</script>
今の編集で行ったこと
- MyBook.vueでbookとuserに関してv-bindディレクティブで単方向のデータバインディングをした。
- App.vueでv-slot:default='slotProp'として子コンポーネントからスロットプロパティを受け取れるようにした。
- スロットプロパティからそれぞれの情報(book,user)を参照した。
スロットプロパティとは?
スロットプロパティとは何でしょうか?スロットプロパティはslot属性でバインドされているプロパティのことです。今回で言うとbook,userとなります。
親コンポーネントの方でslotProp(名前は任意)とすることで子コンポーネントからスロットプロパティをオブジェクト形式で受け取ることができます。
slotProp: {
book: {
title: 'これからはじめるvue.js実践入門',
price: 3000,
publish: 'SBクリエイティブ'
},
user: {
name: 'sin-sudo',
age: 20,
gender: 'male'
}
}
イメージこんな感じですかね。これで親コンポーネントの方で{{ slotProp.book.title }}などのようにしてアクセスすることができるようになります。
最後に
スコープ付きスロットの使い方についてまとめました。間違いあれば是非ご指摘お願いします。