slot在使用时:
<slot name="slotName"></slot>
在组件中定义时:<template v-slot:slotName></template>
v-slot 只能添加在<template>
上 (只有一种例外情况),这一点和已经废弃的 slot attribute 不同
具名插槽
子组件:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父组件:
<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>
作用域插槽
<span>
<slot v-bind:user="user"><!--绑定在 <slot> 元素上的 attribute 被称为插槽 prop-->
{{ user.lastName }}
</slot>
</span>
现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
独占默认插槽的缩写语法(v-slot可以不绑定在<template>
)
在上述情况下,当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。
<current-user v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</current-user>
可以更简单的写:
<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>
可以这么写:统一写成具名插槽且<template>
<current-user >
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
slotProps is NOT available here
</template>
</current-user>
解构插槽 Prop
作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里
v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式
ES2015 解构来传入具体的插槽 prop,如下:
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
可以重新命名:
<current-user v-slot="{ user : person }">
{{ person.firstName }}
</current-user>
可以定义后备内容:
<current-user v-slot="{ user = { firstName: 'Guest' } }">
{{ user.firstName }}
</current-user>
动态插槽名 2.6.0 新增
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:v-slot:[dynamicSlotName]
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
动态指令参数
dynamicSlotName:动态参数,必须是字符串。如果有空格或者引号拼接的,都会警告,内容不会执行。
当然,复杂的可以使用计算属性。
<a v-bind:[attributeName]="url"> ... </a>
如果:attributeName为"href",则<a v-bind:["href"]="url"> ... </a>
<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>
在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:
<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>
具名插槽的缩写:v-slot:
可以简写为#
<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>