详解vue 2.6 中 slot 的新用法
最近发布不久的Vue2.6,使用插槽的语法变得更加简洁。对插槽的这种改变让我对发现插槽的潜在功能感兴趣,以便为我们基于Vue的项目提供可重用性,新功能和更清晰的可读性。真正有能力的插槽是什么?
如果你是Vue的新手,或者还没有看到2.6版的变化,请继续阅读。也许学习插槽的最佳资源是Vue自己的文档,但是我将在这里给出一个纲要。
想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!
插槽是什么?
插槽是Vue组件的一种机制,它允许你以一种不同于严格的父子关系的方式组合组件。插槽为你提供了一个将内容放置到新位置或使组件更通用的出口。从一个简单的例子开始:
//frame.vue
这个组件最外层是一个div。假设div的存在是为了围绕其内容创建一个样式框架。这个组件可以通用地用于将框架包围在wq你想要的任何内容上,来看看它是怎么用的。这里的frame组件指的是我们刚才做的组件。
//app.vue
在开始和结束frame标记之间的内容将插入到插槽所在的frame组件中,替换slot标记。这是最基本的方法。还可以简单地通过填充指定要放入槽中的默认内容
//frame.vue
如果这里没有指定任何内容,这就是默认内容
所以现在如果我们这样使用它:
//app.vue
“如果这里没有指定任何内容,这就是默认内容”是默认内容,但是如果像以前那样使用它,默认文本将被img标记覆盖。
多个/命名的插槽
可以向组件添加多个插槽,但是如果这样做了,那么除了其中一个之外,其他所有插槽都需要有名称。如果有一个没有名称的槽,它就是默认槽。下面是如何创建多个插槽:
//titled-frame.vue
如果这里没有指定任何内容,这就是默认内容
我们保留了相同的默认槽,但这次我们添加了一个名为header的槽,可以在其中输入标题,用法如下:
//app.vue
MyImage'sTitle
就像之前一样,如果我们想将内容添加到默认槽中,只需将其直接放在titled-frame组件中。但是,要将内容添加到命名槽中,我们需要用v-slot指令将代码包裹在在template标记中。在v-slot之后添加冒号(:),然后写出要传递内容的slot的名称。
注意,v-slot是Vue2.6的新版本,所以如果你使用的是旧版本,则需要阅读关于不推荐的slot语法的文档。
作用域插槽
还需要知道的另一件事是插槽可以将数据/函数传递给他们的孩子。为了证明这一点,我们需要一个完全不同的带有插槽的示例组件:创建一个组件,该组件将当前用户的数据提供给其插槽:
//current-user.vue
{{user.lastName}}
该组件有一个名为user的属性,其中包含关于用户的详细信息。默认情况下,组件显示用户的姓,但请注意,它使用v-bind将用户数据绑定到slot。这样,我们就可以使用这个组件向它的后代提供用户数据
//app.vue
{{slotProps.user.firstName}}
为了访问传递给slot的数据,我们使用v-slot指令的值指定作用域变量的名称。
这里有几点需要注意:
- 我们指定了default的名称,但是不需要为默认槽指定名称。相反,我们可以使用v-slot="slotProps"。
- 不需要使用slotProps作为名称,可以随便叫它什么。
- 如果只使用默认槽,可以跳过内部template标记,直接将v-slot指令放到当前current-user上。
- 可以使用对象解构来创建对作用域插槽数据的直接引用,而不是使用单个变量名。换句话说,可以使用v-slot="{user}"代替v-slot="slotProps",然后可以直接使用user而不是slotProps.user。
所以,上面的例子可以这样重写
//app.vue
{{user.firstName}}
还有几点要记住:
- 可以使用v-bind指令绑定多个值。
- 也可以将函数传递到作用域槽。许多库使用它来提供可重用的函数组件。
- v-slot的别名是#。因此,可以用#header="data"来代替v-slot:header="data"。还可以使用#header来代替v-slot:header(前提:不是作用域插槽时)。对于默认插槽,在使用别名时需要指定默认名称。换句话说,需要这样写#default="data"而不是#="data"。
可以从文档中了解更多的细节,但这足以帮助你理解在本文剩下部分中讨论的内容。
你能用插槽做什么?
插槽不是为了一个目的而构建的,或者至少如果它们是,它们已经超越了最初的意图,成为做许多不同事物的强大工具。
可重用的模式
组件总是被设计为可重用的,但是某些模式对于使用单个“普通”组件来实施是不切实际的,因为为了自定义它,需要的props数量可能过多或者需要通过props传递大部分内容或其它组件。
插槽可用包裹外部的HTML标签或者组件,并允许其他HTML或组件放在具名插槽对应名称的插槽上。
对于的第一个例子,从简单的东西开始:一个按钮。假设咱们的团队正在使用Bootstrap。使用Bootstrap,按钮通常与基本的“btn”类和指定颜色的类绑定在一起,比如“btn-primary”。你还可以添加size类,比如'btn-lg'。
为了简单起见,现在让我们假设你的应用使用btn、btn-primary和btn-lg。你不希望总是必须在按钮上写下这三个类,或者你不相信新手会记得写下这三个类。
在这种情况下,可以创建一个自动包含所有这三个类的组件,但是如何允许自定义内容?prop不实用,因为允许按钮包含各种HTML,因此我们应该使用一个插槽。
ClickMe!
现在我们可以在任何地方使用它,无论你想要什么内容
我是小智!
当然,你可以选择比按钮更大的东西。坚持使用Bootstrap,让我们看一个模态:
×