开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情
一、简介
slot 是对子组件的扩展可以通过<slot>插槽向子组件内部指定位置传递内容
插槽出口<slot>
<slot> 元素是一个插槽出口,表示了父元素提供的插槽内容(slot content)在哪里被渲染 插槽内容可以是任意合法的模板内容,不局限于文本。 插槽的显示位置由子组件决定
slot 和props 的区别
设计思想
props设计思想是传递状态,贯彻数据驱动组件的概念,子组件的渲染取决于父组件传递的数据 slot 设计思想是传递DOM节点,将父组件的模板代码节点直接传递给子组件的某个slot
作用范围
父组件在调用子组件的时候申请并赋值变量,子组件内将其加入props列表后,就可以接收并使用,但是一旦传递过来,作用域就发生变化, 子组件虽然为父组件预留slot,但是slot的作用域依然属于父组件,可以访问到父组件内的所有状态。 插槽内容无法访问子组件的数据,
二、slot 类型
匿名插槽(默认插槽)
没有设置name属性的插槽 在组件只有一个插槽时,可不设置slot name 属性,父组件使可v-slot 后可以不带参数, 注意: 插槽可以放置在组件的任意位置, 一个组件只有一个匿名插槽 匿名插槽只能作为没有slot属性的元素的插槽
//chile.vue
<div class="child">
<h1>子组件</h1>
<slot name="head">头部默认值</slot>
<slot>这是个匿名插槽(没有name属性)</slot>
<slot name="body">主体默认值</slot>
</div>
//parent.vue
<div class="parent">
<h1>父组件</h1>
<child>
<p slot="head">我是头部</p>
<p>我是其他内容</p>
</child>
</div>
结果
我是头部 (具名插槽name 默认值被覆盖)
我是其他内容 (匿名插槽 默认值被覆盖)
主体默认值(具名插槽body 默认值被渲染)
具名插槽
带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 <slot> 出口会隐式地命名为“default”。
v-slot 有对应的简写 #,因此 <template v-slot:header> 可以简写为 <template #header>。 <template v-slot:插槽名称>插槽内容</template> 等于 <p slot="插槽名称">插槽内容</p>
一个组件可以由很多具名插槽,具名插槽可以出现在任意位置 注意:
- 带有 v-slot 的
<template>元素中的所有内容都将会被传入相应的插槽。 - 任何没有被包裹在带有 v-slot 的
<template>中的内容都会被视为默认插槽的内容。 - slot 可以用在任何元素上,v-slot 只能添加在
<template>上 - 当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非
<template>节点都被隐式地视为默认插槽的内容
作用域插槽
同时使用父组件域内和子组件域内的数据,让子组件在渲染时将一部分数据提供给插槽,可以相对组件传递props,向上一个插槽的出口传递attributes
//1、使用v-slot 接收
<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
//2、结构赋值
<MyComponent v-slot="{ text, count }">
{{ text }} {{ count }}
</MyComponent>
//3具名插槽传值
<MyComponent>
<template #header="headerProps">
{{ headerProps }} //headerProps 是{message:hello} key-value 形式
</template>
<template v-slot:footer="footerProps">
{{ footerProps }}
</template>
<template #default="defaultProps">
{{ defaultProps }}
</template>
</MyComponent>
// 插槽
<slot name="header" message="hello"></slot>