小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
1.插槽小栗子
在我们封装组件的时候,我们可能会遇到这种情况,这个组件的功能是我们需要的可是ui界面不是我们需要的
对于这种情况,就需要用到slot 插槽
来个简单的小栗子
子组件:(<navigation-link>的模板中可能会写为:)
<a v-bind:href="url" class="nav-link" >
<slot></slot>
</a>
父组件使用
<navigation-link url="/profile">
Your Profile
</navigation-link>
当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML:
<navigation-link url="/profile">
<!-- 添加一个 Font Awesome 图标 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
甚至其它的组件:
<navigation-link url="/profile">
<!-- 添加一个图标的组件 -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
但是 如果 <navigation-link> 的 template 中没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
2.后备内容(我也喜欢叫做默认内容)
每次都为插槽添加内容也是麻烦的要死,在我们开发的时候也不可能都是每个功能都需要一样,而ui展示是完全不一样的,有人的地方就有需求,有需求才能更好的生产
后备内容应运而生:
子组件: submit-button.vue
<button type="submit">
<slot>Submit</slot>
</button>
父组件使用:
现在当我在一个父级组件中使用 <submit-button> 并且不提供任何插槽内容时:
<submit-button></submit-button>
后备内容“Submit”将会被渲染;
但是如果我们提供内容:
<submit-button> Save </submit-button>
父组件提供的内容“Save”将会被渲染从而取代后备内容
3.具名插槽
有时我们需要多个插槽。例如对于一个带有如下模板的 <base-layout> 组件:
<div class="container">
<header>
<!-- 我们希望把页头放这里 -->
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
</main>
<footer>
<!-- 我们希望把页脚放这里 -->
</footer>
</div>
对于这样的情况, 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
一个不带 name 的 <slot> 出口会带有隐含的名字default。
在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
当然你也可以写的更加明确一些
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
任何一种写法都会渲染出:
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
效果如下:
Here might be a page title
A paragraph for the main content.
And another one.
Here's some contact info
------------------------华丽的分割线----------------------------
顺嘴一提,这个颜色这个是掘金的样式导致的,别误会了哈
注意 v-slot 只能添加在
<template>上 !!!!!!!!!!!
4.作用域插槽
有时让插槽内容能够访问子组件中才有的数据是很有用的。
但是 我们子组件在父组件中进行渲染的时候,对插槽进行提供的数据只能是父组件的
就像这样
子组件:
<span>
<slot>{{ user.lastName }}</slot>
</span>
我们可能想换掉备用内容:
像这样:
<current-user> {{ user.firstName }} </current-user>
但是这里插槽渲染的 user.firstName 却是父组件下面的 user.firstName 而不是 子组件下的,为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 <slot> 元素的一个 attribute 绑定上去:
<span>
<slot v-bind:user="user"> {{ user.lastName }} </slot>
</span>
绑定在 <slot> 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:
<current-user>
<template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template>
</current-user>
在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字。
当然 v-slot:default === v-slot 也是可以的
但是在多个的是 就需要 v-slot:default 而不是 v-slot了
注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确
只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法:
<current-user>
<template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template>
<template v-slot:other="otherSlotProps"> {{ otherSlotProps.user.firstName }} </template>
</current-user>
5.具名插槽的缩写
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:
<!-- 这样会触发一个警告 -->
<current-user #="{ user }"> {{ user.firstName }} </current-user>
如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:
<current-user #default="{ user }"> {{ user.firstName }} </current-user>
总结
我们学会了 solt的各种使用方式
- 默认插槽
- 具名插槽
- 作用域插槽
- 具名插槽缩写 喜欢的点个赞吧!! 求求了