作为目前最流行的树型JavaScript框架之一,Vue值得关注。它非常容易学习,使用并让您喜欢它做事的方式。
在本文中,我们将讨论其强大的功能,插槽,并简要说明它们是什么以及如何使用它们。最后,重点将放在将所有插槽从父组件传递到子组件上。
本文假定您对Vue插槽及其工作原理有一定的了解
不过,我将提供一些简短的解释。好吧,让我们深入研究它。
什么是Vue插槽? {#what-are-vue-slots}
我们可以将它们定义为自定义元素,从而使我们能够为组件创建自定义的动态内容。它们具有保留名称slot
,我们可以将它们创建为默认插槽或命名插槽。同样,它们可以解释为预定义的组件。
每个广告位都有自己的范围和后备内容。插槽的范围与使用该插槽的模板的范围相同,这意味着我们的插槽将无法访问其代表内容的组件的范围。在下一节中,您可以看到示例,希望前面的句子会更清楚。
接下来是回退内容,即广告位的开始和结束标签之间的内容,它表示当使用组件的模板中未提供广告位时要显示的默认值。基本上,我们确保页面上始终显示某些内容,即广告位内容或默认值。
如何使用Vue插槽? {#how-to-use-vue-slots}
为了从外部为组件提供动态内容,我们需要做的就是将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命名插槽? {#how-to-use-vue-named-slots}
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作用域插槽? {#how-to-use-vue-scoped-slots}
在上一节中,我已经提到了插槽的范围与使用它的模板的范围相同。有时,这还不够好,在某些情况下,我们希望获得子组件的作用域。值得庆幸的是,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
伪指令可以告诉框架哪个插槽应具有所提供的回退内容。
将插槽传递给子组件 {#pass-the-slots-to-the-child-component}
好的,这就是为什么我们在这里。现在该展示如何从父组件到子组件传递所有插槽。
如您所料,我们需要创建一个带有槽的模板,因为它是我们要从父级传递到子级的每个槽的内容,并且有两种方法可以做到这一点。第一种方法是手动执行此操作,为每个插槽创建一个模板元素,如果我们有一个或两个插槽,则可以,但是如果我们要传递更多的插槽,该怎么办?我们是否应该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
在子组件中定义了一个,并在应用程序根目录中为其提供了内容。父组件只是将所有插槽都传递给了子组件,这就是我想通过撰写本文向您展示的内容。