插槽的设计目的是:子组件的模板在一定程度上是可变的,父组件可以根据自己的需要修改子组件模板的指定部分。相当于子组件提供了一个“插槽”,父组件按照约定将模板块插入到子组件中。这个插入的模板块只能访问父组件的数据,不能访问子组件的数据,因为它是定义在父组件中的,需要访问的子组件的数据需要通过插槽属性传入。
默认插槽
当子组件中声明了 slot 元素后,使用子组件时子组件的 innerHTML 将会替换掉 slot 元素,达到父组件向子组件插入内容的目的。如果子组件没有声明 slot 元素,innerHTML 将会被丢弃。slot 元素可以有 HTML 内容,该内容将会作为插槽的默认内容。
const Son = {
template: `<p><slot>This is default title</slot></p>`
}
const Father = {
components: { son: Son },
template: `<son>This is title</son>`
}
父组件的<son>This is title</son>
实际上是<son><template v-slot:default>This is title<template></son>
的简写,其中v-slot:
部分还可以进一步缩写为#
,即<son><template #default>This is title<template></son>
,当然<template #default><template>
可以省去,最后变为默认 innerHTML 的样式。
具名插槽
一个 slot 元素只能表示一个插槽,父组件通过 innerHTML 或者<template #default>
来填充插槽的内容。
一个组件可以声明多个插槽,其他插槽需要使用不同的名字,插槽的名字使用 slot 元素的name
属性来指定
<slot name="header"></slot>
<slot name="footer"></slot>
父组件中通过v-slot:插槽名
的格式来为指定名称的插槽插入内容
<template v-slot:header>this is header</template>
<template v-slot:footer>this is footer</template>
v-slot
指令可以简写为#
<template #header>this is header</template>
<template #footer>this is footer</template>
v-slot
指令只能添加到子组件中的template
标签上,当只有默认插槽时,v-slot
指令可以直接写在子组件的标签上。
插槽访问子组件数据
父组件插入的内容只能访问父组件的数据,如果需要访问子组件的数据,需要通过 slot 元素的属性传入
<li v-for="(d, i) in users">
<slot :user="d" :index="i"></slot>
</li>
<son>
<template v-slot:default="slotProps">
{{ slotProps.user }} - {{ slotProps.index }}
</template>
</son>
父组件中通过给v-slot:SLOTNAME
属性指定值来获取子组件传递给给插槽的数据。
slotProps
实际上收集了子组件中 slot 元素的所有自定义属性,他是一个 JS 对象,所以可以通过解构获取具体的属性,对象解构 的重命名和默认值等特性都可以使用。
<son>
<template v-slot:default="{ user: userRaw, index = '-1' }">
{{ userRaw }} - {{ index }}
</template>
</son>
当子组件只声明了默认插槽时,v-slot:default="{ user, index }"
可以简写为v-slot="{ user, index }"
。
动态插槽名
插槽名除了字面量外,也可以是变量
<template>
<son>
<template v-slot:[slotName]></template>
</son>
</template>
<script>
export default {
data() {
return {
slotName: 'header'
}
}
}
</script>
插槽指令的缩写
v-slot
被认为是默认插槽,而它的等价写法v-slot:default
被认为是具名插槽。
只有具名插槽才能使用缩写形式,缩写时将v-slot:
替换为#
,即#default
, #header
等。
其他缩写指令:
v-bind:key="value"
缩写为:key="value"
,特别的v-bind:key="true"
可以缩写为key
v-on:event="callback"
缩写为@event="callback"
评论区