×

分享Vue开发小技巧:将插槽传递给子组件

作者:Terry2020.11.04来源:Web前端之家浏览:16876评论:2
关键词:jsvue

作为目前最流行的树型JavaScript框架之一,Vue值得关注。它非常容易学习,使用并让您喜欢它做事的方式。

在本文中,我们将讨论其强大的功能,插槽,并简要说明它们是什么以及如何使用它们。最后,重点将放在将所有插槽从父组件传递到子组件上。

本文假定您对Vue插槽及其工作原理有一定的了解

不过,我将提供一些简短的解释。好吧,让我们深入研究它。

什么是Vue插槽?

我们可以将它们定义为自定义元素,从而使我们能够为组件创建自定义的动态内容。它们具有保留名称slot,我们可以将它们创建为默认插槽或命名插槽。同样,它们可以解释为预定义的组件。

每个广告位都有自己的范围和后备内容。插槽的范围与使用该插槽的模板的范围相同,这意味着我们的插槽将无法访问其代表内容的组件的范围。在下一节中,您可以看到示例,希望前面的句子会更清楚。

接下来是回退内容,即广告位的开始和结束标签之间的内容,它表示当使用组件的模板中未提供广告位时要显示的默认值。基本上,我们确保页面上始终显示某些内容,即广告位内容或默认值。

如何使用Vue插槽?

为了从外部为组件提供动态内容,我们需要做的就是将slot元素放在组件模板中的想要显示自定义内容的位置。查看一个简单的示例组件:

组件模板:

<template>
  <div>
    <span>Inner Content</span>
    <slot>Default Content</slot> <!-- This is where the maging happens -->
  </div>
</template>

在外面,在我们应用程序中的某个位置:


<example>
  This text is going to be rendered instead of the element within our example component
</example>

另一方面,如果我们像这样使用组件:


<example />

回退将要呈现,在本例中为Default Content文本。

没有名称的插槽将由Vue框架将此属性设置为“默认”

如何使用Vue命名插槽?

Vue名为slot就是name配置了属性的slot元素。当我们希望在组件模板中的不同位置呈现不同的动态内容时,这非常有用。让我们更新示例组件。

<template>
  <section>
    <header>
      <slot name="title">Title</slot>
    </header>
    <main>
      <slot>Content</slot>
    </main>
  </section>
</template>

在我们应用程序中的某个位置:


<example>
  <template v-slot:title>
    My Component Title
  </template>
  <p>My Component Content</p>
</example>

可以假设,模板元素内的所有内容都将呈现在组件内部相应插槽的位置,而模板元素内的所有内容都将呈现在默认插槽的位置。我们通过使用v-slot指令来实现此目的,其后是要向其传递动态内容的插槽的名称。

如何使用Vue作用域插槽?

在上一节中,我已经提到了插槽的范围与使用它的模板的范围相同。有时,这还不够好,在某些情况下,我们希望获得子组件的作用域。值得庆幸的是,Vue支持这一点,并使我们能够在组件之间传递范围。让我们用一个示例对此进行备份。

我们的组件模板:

<template>
  <section>
    <slot>{{user.name}}</slot>
  </section>
</template>

js代码:


export default {
  name: 'example',
  data() {
    return {
      user: {
        name: 'John',
        surname: 'Doe'
      }
    }
  }
}

在我们应用程序的某个地方,我们使用如下组件:


<example>
  Fallback content
</example>


此时,我们的后备内容不能基于user数据,因为数据是在示例组件中定义的,并且广告位的内容在父组件中呈现。

这是示波器插槽进入图片的位置。要将范围传递给父级,我们需要将示例组件模板更改为如下所示:

<template>
  <section>
    <slot v-bind:user="user">{{user.name}}</slot>
  </section>
</template>

通过该v-bind指令,我们可以将用户对象绑定到用户属性,现在,我们可以在父组件模板中使用用户数据。


<example>
  <template v-slot:default="props">
    {{ props.user.name }} {{props.user.surname }}
  </template>
</example>

在上一节中,我提到了未命名的插槽,其隐含名称为“ default”,并使用v-slot伪指令可以告诉框架哪个插槽应具有所提供的回退内容。

将插槽传递给子组件

好的,这就是为什么我们在这里。现在该展示如何从父组件到子组件传递所有插槽。

如您所料,我们需要创建一个带有槽的模板,因为它是我们要从父级传递到子级的每个槽的内容,并且有两种方法可以做到这一点。第一种方法是手动执行此操作,为每个插槽创建一个模板元素,如果我们有一个或两个插槽,则可以,但是如果我们要传递更多的插槽,该怎么办?我们是否应该n在父组件中包含模板?好吧,不,这是一个非常冗长且不切实际的解决方案,在这种情况下,我们将使用第二种方法,并通过for...each循环动态呈现模板。

您可能想知道我们要迭代哪个集合?不用担心,Vue涵盖了!我们定义的每个广告位将存储在以下集合之一中:

  • $ slots

  • $ scopedSlots

从2.6.0+开始,所有$ slots现在都在$ scopedSlots中公开为函数

上面的文字可能不胜枚举,但我希望以下示例能帮助您理解。

传递代码$slots

<template v-for="(index, name) in $slots" v-slot:[name]>
  <slot :name="name" />
</template>

传递代码$scopedSlots需要更多配置,但这类似于传递代码$slots


<template v-for="(index, name) in $scopedSlots" v-slot:[name]="data">
  <slot :name="name" v-bind="data"></slot>
</template>

通过在父组件中定义这样的模板,我们传递了在使用父组件的位置定义的所有插槽。

如您所见,我们已经child-slot在子组件中定义了一个,并在应用程序根目录中为其提供了内容。父组件只是将所有插槽都传递给了子组件,这就是我想通过撰写本文向您展示的内容。

您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://www.jiangweishan.com/article/vue20201104a1.html

网友评论文明上网理性发言 已有2人参与

发表评论:

评论列表