エンジニアの卵の成長日記

https://blog.toru-takagi.dev/profile/

Riot.jsのyield内でテンプレート変数を利用する方法

yieldとは?

カスタムタグ内で</yield>を入れることで、

タグをカスタムタグで囲うことで、中身が<yield>部分に出力されます。

index.html

<body>
  <custome>
    <p>ここに内容を記載します。</p>
  </custome>
</body>

<custome>
  <h1>タイトル</h1>
  </yield>
</custome>

上記を実行すると、以下のように部分に入ります。

<body>
  <custome>
    <h1>タイトル</h1>
    <p>ここに内容を記載します。</p>
  </custome>
</body>

テンプレート変数が使えない!?

カスタムタグ内で、他のカスタムタグを呼び出すことは、よくあると思います。

そこで、テンプレート変数を使おうとするとうまく動きません。

<custom>
  <h1>タイトル</h1>
  </yield>
</custom>

<caller>
  <custom>
    <p>{ contents }</p>
  </custom>
  <script>
    var tag = this
    this.contents = 'ここに内容を記載します。'
  </script>
</caller>

上手くいきそうな気がしますが、結果は以下の通り

<caller>
  <custom>
    <h1>タイトル</h1>
    <p></p>
  </custom>
</caller>

</yield>に入った場合、テンプレート変数の参照は、そのカスタムタグに

<custom>
  <h1>タイトル</h1>
  </yield>
  <script>
    var tag = this
    tag.contents = 'こっちだよ。'
  </script>
</custom>

<caller>
  <custom>
    <p>{ contents }</p>
  </custom>
  <script>
    var tag = this
    tag.contents = 'ここに内容を記載します。'
  </script>
</caller>

</yield>を宣言している方のJSオブジェクトを参照するみたい

<caller>
  <custom>
    <h1>タイトル</h1>
    <p>こっちだよ。</p>
  </custom>
</caller>

解決策

子要素にデータを渡してあげる

<custom>
  <h1>タイトル</h1>
  </yield>
</custom>

<caller>
  <custom contents={ contents }>
    <p>{ opts.contents }</p>
  </custom>
  <script>
    var tag = this
    tag.contents = 'ここに内容を記載します。'
  </script>
</caller>

子要素のタグにデータをセットcontents={ contents }

テンプレート変数でオプションを参照するように修正opts.contents

キャメルケースにすると参照されない

子要素のタグにデータを渡す際に、キャメルケースで記載すると上手く動かなくなります。

<custom>
  <h1>タイトル</h1>
  </yield>
</custom>

<caller>
  <custom contentsMessage={ contentsMessage }>
    <p>{ opts.contentsMessage }</p>
  </custom>
  <script>
    var tag = this
    tag.contentsMessage = 'ここに内容を記載します。'
  </script>
</caller>

ケバブケースで記載をすれば上手くいきます。

<custom>
  <h1>タイトル</h1>
  </yield>
</custom>

<caller>
  <custom contents-message={ contentsMessage }>
    <p>{ opts.contentsMessage }</p>
  </custom>
  <script>
    var tag = this
    tag.contentsMessage = 'ここに内容を記載します。'
  </script>
</caller>

contentsMessagecontents-messageに変更

最後に

最近、業務でRiot.jsを使うようになったのですが、 (今更...)

本当にシンプルなのに高機能!

Vue.jsに負けず劣らず、触っていて楽しい。

これからちょっとずつRiot.jsの記事を書いていけたらと思います笑

twitter.com