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 компонент для создания новых столбцов.

Как я мог этого достичь? Использует слот лучший подход?

спасибо заранее.

2 ответов


слоты-лучший подход, и вам нужно будет использовать слот с областью действия для contact-list-item компонент. Я не очень хорошо знаком с pug, поэтому я буду использовать HTML для примера.

на contact-list вы бы добавить слот. Обратите внимание, что в этом случае контакт передается как свойство. Это для того, чтобы мы могли воспользоваться scoped слоты.

<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.


можно использовать template для регистрации слота для дочернего дочернего компонента.

существует также случай, когда вы хотите иметь много именованных слотов.

ребенок.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>

внука.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>

родитель.vue

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