本篇(可能此系列会包含不少篇)纯属从Vue官方文档找来的内容,也可能会根据自身的知识状况扩展、延伸、概括,进行个性化总结排版,方便本身记录和查阅。bash
在Vue2.6.0中具名插槽和做用域插槽引入了新的统一的语法(v-slot指令)。它取代了 slot 和slot-scope两个特性。url
当父级模板里的内容编译时只会在父级做用域里生效;子模板里的全部内容都是在子做用域里编译。 例子:spa
# <navigation-link> 组件
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
复制代码
该插槽跟模板的其它地方同样能够访问相同的实例属性 (也就是相同的“做用域”),而不能访问 的做用域。例如 url 是访问不到的:code
<navigation-link url="/profile">
Clicking here will send you to: {{ url }}
<!--
这里的 `url` 会是 undefined,由于 "/profile" 是
_传递给_ <navigation-link> 的而不是
在 <navigation-link> 组件*内部*定义的。
-->
</navigation-link>
复制代码
有时咱们须要多个插槽。例如对于一个带有以下模板的 组件:作用域
<div class="container">
<header>
<!-- 咱们但愿把页头放这里 -->
</header>
<main>
<!-- 咱们但愿把主要内容放这里 -->
</main>
<footer>
<!-- 咱们但愿把页脚放这里 -->
</footer>
</div>
复制代码
元素有一个特殊的特性:name。这个特性能够用来定义额外的插槽:文档
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
复制代码
一个不带 name 的 出口会带有隐含的名字“default”。string
在向具名插槽提供内容的时候,咱们能够在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称: it
<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> 复制代码
如今 元素中的全部内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 中的内容都会被视为默认插槽的内容。 若是想更明确一些,仍然能够在一个 中包裹默认插槽的内容: io
<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> 复制代码
注意 v-slot 只能添加在一个 上, 只有一种例外状况:
当被提供的内容只有默认插槽时,组件的标签才能够被看成插槽的模板来使用。这样咱们就能够把 v-slot 直接用在组件上:
<current-user v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</current-user>
复制代码
这种写法还能够更简单。就像假定未指明的内容对应默认插槽同样,不带参数的 v-slot 被假定对应默认插槽:
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>
复制代码
注意默认插槽的缩写语法不能和具名插槽混用,由于它会致使做用域不明确:
<!-- 无效,会致使警告 -->
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
<template v-slot:other="otherSlotProps">
slotProps is NOT available here
</template>
</current-user>
复制代码
只要出现多个插槽,请始终为全部的插槽使用完整的基于 的语法:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user>
复制代码
***动态指令***参数也可使用在 v-slot 上,来定义动态的插槽名:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
复制代码
跟 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>
复制代码