Vue.js の scoped slot の理解

毎回混乱して、ドキュメントを読んでいるのでまとめ。

以下のようなスロットの機能を利用したコンポーネント child で考える。

<div>
  {{ foo }}
  <child>
     <span>{{ bar }}</span>
  </child>
  {{ baz }} 
</div>

https://jp.vuejs.org/v2/guide/components.html#コンパイルスコープ に書いてある話ですが、上記のテンプレートの foo, bar, baz のスコープは、そのテンプレートを扱っているコンポーネントになる。なんとなく、bar を展開している場所のスコープは child のような気がしてくるのだけど、そうではない。

bar を展開している場所で child のスコープを扱いたい( child のステートで class の付け替えをしたり )場合は、以前までは、child のステートを親のコンポーネントに渡し、親のコンポーネントを通してステートを展開していた。これは、親と子のコンポーネントが密になるのでよろしくない。

この問題を解決するのが scoped slot。child 内の slot コンポーネントに渡したデータが scope 属性値のオブジェクトを通して参照できるようになる。

<!-- child のテンプレート -->
<div>
  <scope :bar="..."></scope>
</div>
<div>
  {{ foo }}
  <child>
     <template scope="props">
       <span>{{ props.bar }}</span>
     </template>
  </child>
  {{ baz }} 
</div>

コンポーネントの親子間でプロパティを通してデータを渡すイメージに近く、属性値の scope の名は props と付けることが多い気がする( ドキュメントもそうなっている )。