【问题标题】:VueJS - Pass slot to child of child componentVueJS - 将插槽传递给子组件的子组件
【发布时间】:2017-12-06 21:09:35
【问题描述】:

我有一个列表和一个 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 组件中呈现的特定联系人的数据来生成新列。

我怎样才能做到这一点?使用插槽是最好的方法吗?

提前致谢。

【问题讨论】:

    标签: javascript vue.js components vuejs2 vue-component


    【解决方案1】:

    插槽是最好的方法,您需要为contact-list-item 组件使用范围插槽。我对 pug 不是很熟悉,所以我以 HTML 为例。

    contact-list 中,您将添加一个插槽。请注意,在这种情况下,联系人是作为属性传递的。这样我们就可以利用scoped slots

    <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 模板中,使用 scoped 模板。

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

    这是working example。我不知道您的样式是什么,但请注意 id 列现在显示在 contact-list-item 中。

    【讨论】:

      【解决方案2】:

      您可以使用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>
      

      【讨论】:

        【解决方案3】:

        将几个slot下移一层方便使用at this link描述的方法,稍微修改一下,说不定可以更深的传递。

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
        猜你喜欢
        • 1970-01-01
        • 2018-09-14
        • 2020-04-23
        • 2018-11-11
        • 2021-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-25
        相关资源
        最近更新 更多