Vue.js 3 - 将组件插入插槽

Posted

技术标签:

【中文标题】Vue.js 3 - 将组件插入插槽【英文标题】:Vue.js 3 - inserting component into slot 【发布时间】:2021-04-03 14:40:41 【问题描述】:

我正在努力实现的目标

我正在尝试将Component 传递给slot

问题/信息

如何将Component 传递到slot 以便它被渲染?只要我传递字符串/纯 html,它就可以正常工作。

其他问题

如果这是不可能的 - 那么我怎样才能将组件传递给具有如下结构的其他组件?

家长

模板代码

<template>
  <card-with-title card-title="Title">
    <template #card-body>
      <row-fontawesome-icon-with-text v-for="mailDto in lastProcessedEmails"/>
    </template>
  </card-with-title>
</template>

脚本代码 - 重要部分

<script>
import SymfonyRoutes                     from '../../../../../core/symfony/SymfonyRoutes';
import GetLastProcessedEmailsResponseDto from '../../../../../core/dto/api/internal/GetLastProcessedEmailsResponseDto';
import MailDto                           from '../../../../../core/dto/modules/mailing/MailDto';

import CardWithTitleComponent              from '../../../../base-layout/components/cards/card-with-title';
import RowFontawesomeIconWithTextComponent from '../../../../other/row-fontawesome-icon-with-text';

export default 
  components: 
    'card-with-title'                : CardWithTitleComponent,
    'row-fontawesome-icon-with-text' : RowFontawesomeIconWithTextComponent,
  ,
<...>

儿童

<!-- Template -->
<template>
  <div class="col-12 col-lg-4 mb-4">
    <div class="card border-light shadow-sm">
      <div class="card-header border-bottom border-light">
        <h2 class="h5 mb-0"> cardTitle </h2>
      </div>
      <div class="card-body">
        <slot name="card-body"></slot>
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<!-- Script -->
<script>
export default 
  props: [
      "cardBody",
      "cardStyle",
      "cardTitle"
  ],

</script>

我对这个问题进行了研究,我在文档中看到了命名插槽的工作方式,但没有帖子/博客条目回答/解决我的问题。

检查资源示例:

https://www.smashingmagazine.com/2019/07/using-slots-vue-js/ How to insert named slots into parent components https://medium.com/js-dojo/vue-named-slot-shorthand-8a920358e861 https://v3.vuejs.org/guide/component-slots.html https://medium.com/@norton.seanm/vue-js-slots-8a274c80450e

【问题讨论】:

@Volmarg 您的模板应该可以正常工作(请参阅demo)。您遇到什么问题? 【参考方案1】:

我找到了解决方案……这非常……可怕。 Vue 检查数组是否为空,在 v-for 上它会尝试循环然后抛出错误。

就个人而言,来自其他语言/框架 - 这不应该发生。

不过,这就是解决方案:

<!-- Template -->
<template>

  <card-with-title card-title="Title">
    <template #card-body>
      <div v-if="[lastProcessedEmails.length]">

        <row-fontawesome-icon-with-text v-for="mailDto in lastProcessedEmails">
          <template #icon>
            <i class="font-weight-bold">
              <i v-if="mailDto.status === mailStatusSent"         :class="fontawesomeIconClassesSent"></i>
              <i v-else-if="mailDto.status === mailStatusPending" :class="fontawesomeIconClassesPending"></i>
              <i v-else                                             :class="fontawesomeIconClassesError"></i>
            </i>
          </template>

          <template #title>
             mailDto.subject 
          </template>

          <template #title-context>
             mailDto.created 
          </template>
        </row-fontawesome-icon-with-text>

      </div>
    </template>
  </card-with-title>

</template>

整个问题是:

  data()
    return 
      lastProcessedEmails: [],
    
  ,

lastProcessedEmails 是通过 Axios Call 更新的。

【讨论】:

以上是关于Vue.js 3 - 将组件插入插槽的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 将数据从插槽传递到组件实例

Vue.js高效前端开发 • Vue组件

Vue.js高效前端开发 • Vue组件

Vue.js 将插槽传递给包装好的 Bootstrap-Vue 表组件

Vue.js slot插槽

Vue.js - 从孙插槽组件发射没有将 $emit 事件冒泡到父级