web-dev-qa-db-ja.com

VueJS-子コンポーネントの子にスロットを渡す

アプリケーション内でよく再利用するリストとlist_itemコンポーネントがあります。簡略化された形式で:

contact_list.vue

<template lang="pug">
    .table  
      .table-header.table-row
        .table-col Contact
        .table-col Info

      .table-body
          contact-list-item(v-for='contact in contacts',
                            :contact='contact',
                            @click='doSomething()')

</template>

contact_list_item.vue

<template lang="pug">
.table-row(@click='emitClickEvent')
  .table-col {{ contact.name }}
  .table-col {{ contact.info }}
</template>

特定のコンポーネント内でcontact_listを使用する場合、contact_list_itemコンポーネントに新しい列を追加するスロットを送信できるようにしたいと考えています。このスロットは、そのcontact_list_itemコンポーネント内にレンダリングされている特定の連絡先のデータを使用して、新しい列を生成します。

どうすればそれを達成できますか?スロットを使用するのが最善の方法ですか?

前もって感謝します。

14
felipeecst

スロットが最善の方法であり、contact-list-itemコンポーネントにはスコープスロットを使用する必要があります。パグについてはあまり詳しくないので、例としてHTMLを使用します。

contact-listでは、スロットを追加します。この場合、連絡先がプロパティとして渡されていることに注意してください。これは スコープスロット を利用できるようにするためです。

<div class="table">
  <div class="table-header table-row">  
    <div class="table-col">Contact</div>
    <div class="table-col">Info</div>
  </div>
  <div class="table-body">
    <contact-list-item v-for='contact in contacts'
                       :contact="contact"
                       @click="doSomething"
                       :key="contact.id">
      <slot :contact="contact"></slot>
    </contact-list-item>
  </div>
</div>

次に、contact-list-itemにスロットを追加します。

<div class="table-row" @click="emitClickEvent">
  <div class="table-col">{{contact.name}}</div>
  <div class="table-col">{{contact.info}}</div>
  <slot></slot>
</div>

最後に、Vueテンプレートで、スコープテンプレートを使用します。

<div id="app">
  <contact-list :contacts="contacts">
    <template scope="{contact}">
      <div class="table-col">{{contact.id}}</div>
    </template>
  </contact-list>
</div>

これが 動作例 です。私はあなたのスタイルが何であるかはわかりませんが、id列がcontact-list-itemに表示されていることに注意してください。

10
Bert

templateを使用して、子コンポーネントの子にスロットを登録できます。

多くの名前付きスロットが必要な場合もあります。

child.vue

<template>
  <div>
    <h2>I'm a father now</h2>
    <grandchild :babies="babies">
      <template v-for="(baby, id) in babies" :slot="baby.name">
        <slot :name="baby.name"/>
      </template>
    </grandchild>
  </div>
</template>

grandchild.vue

<template>
  <div>
    <p v-for="(baby, id) in babies" :key="id">
      <span v-if="baby.isCry">Owe...owe...</span>
      <slot :name="baby.name">
    </p>
  </div>
</template>

parent.vue

<template>
  <div>
    <h2>Come to grandpa</h2>
    <child :babies="myGrandChilds">
      <button slot="myGrandChilds[2].name">baby cry</button>
    </child>
  </div>
</template>
1
DrSensor