- 基础
<slot>是一个插槽出口,在子组件中标识了父组件中传递的内容应该在哪里渲染;通过使用插槽子组件只负责渲染(外层的样式及html标签),内部内容由父组件提供。- 插槽内容可以是任意合法模板内容,可传入多个元素或组件
js实现其原理为
// 父元素传入插槽内容
FancyButton('Click me!')
// FancyButton 在自己的模板中渲染插槽内容
function FancyButton(slotContent) {
return `<button class="fancy-btn">
${slotContent}
</button>`
}
其作用域
插槽内容可以访问到父组件的数据作用域,因为其本身是在父组件模板中定义的
默认插槽内容
在外部没有提供任何内容的情况下,可以为插槽指定默认内容
例子:
<button type="submit">
<slot>
Submit <!-- 默认内容 -->
</slot>
</button>
具名插槽
子组件
- 其
<slot>元素拥有一个特殊的name属性可以给各个插槽分配唯一的id,以及确定每一处插槽渲染的内容; 这类插槽被称为:具名插槽。没有提供name的<slot>出口会被隐式命名为default
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父组件
- 在父组件中要给子组件插槽传递内容时,需要用到一个包含
v-slot指令的<template>元素并将目标插槽的名字传给该指令。 v-slot有对应的简写#,比如<template v-slot:name>可以简写为<template #name>- 当一个组件同时接收默认插槽和具名插槽时,所有顶级的非
<template>节点都会被视为默认插槽的内容
<BaseLayout>
<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>
<!--v-slot简写-->
<template #footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>
js函数类比具名插槽
// 传入不同的内容给不同名字的插槽
BaseLayout({
header: `...`,
default: `...`,
footer: `...`
})
// <BaseLayout> 渲染插槽内容到对应位置
function BaseLayout(slots) {
return `<div class="container">
<header>${slots.header}</header>
<main>${slots.default}</main>
<footer>${slots.footer}</footer>
</div>`
}
动态插槽
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</base-layout>
作用域插槽
父组件模板中的表达式只能访问父组件的作用域,子组件模板中的表达式只能访问子组件的作用域。 插槽的内容如何同时使用父组件和子组件域的数据呢?
- 在插槽的出口上传递
attributes(属性)
<!-- <MyComponent> 的模板 -->
<div>
<slot :text="greetingMessage" :count="1"></slot>
</div>
2.在父组件中如何接收子组件传过来的数据呢?
在默认插槽中,是通过子组件标签上的v-slot指令来接收一个插槽对象slotProps
<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
同时也可以使用解构
<MyComponent v-slot="{text,cont}">
{{text}}{{cont}}
<MyComponent/>
具名作用域插槽
v-slot:name="slotPros"可简写为#name="slotProps"
<MyComponent>
<template #header="headerProps">
{{ headerProps }}
</template>
<template #default="defaultProps">
{{ defaultProps }}
</template>
<template #footer="footerProps">
{{ footerProps }}
</template>
</MyComponent>