1.插槽的介绍
我们都清楚父组件可以给儿子组件传递数据,但是如何通过父组件给儿子组件传递内容?很明显,插槽就诞生了。
2.插槽常见作用
- 父组件给儿子组件传递内容
- 父组件给儿子组件传递数据
- 儿子组件给父组件传递数据
3.插槽分类
- 匿名插槽
- 具名插槽
- 作用域插槽
4.不同插槽的介绍
4.1 匿名插槽
4.1.1父组件给儿子插槽不传递内容
Father.vue
<template>
<div>Father</div>
<Son/>
</template>
Son.vue
<template>
<div>Son</div>
<slot>
<div>son title</div>
</slot>
</template>
输出结果:
总结:当父组件给儿子插槽不传递内容时,儿子的插槽使用自己的内容。
4.1.2父组件给儿子插槽传递内容
Father.vue
<template>
<div>Father</div>
<Son>
<div>son tiltle</div>
<div>son content</div>
<div>son footer</div>
</Son>
</template>
Son.vue
<template>
<div>Son</div>
<slot>
<div>son title</div>
</slot>
</template>
输出结果:
总结:父组件给儿子组件的插槽传递数据时,会使用父组件给儿子插槽传递的内容,儿子插槽自定义的内容会被覆盖掉。
4.2 具名插槽(有名称的插槽)
考虑如果子组件有多个插槽,父组件如果想给指定插槽传递指定的内容,如何传递?我们先看看匿名插槽的结果,很明显乱的一批儿子组件插槽内容都一样。
Father.vue
<template>
<div>Father</div>
<Son>
<div>son tiltle</div>
<div>son content</div>
<div>son footer</div>
</Son>
</template>
Son.vue
<template>
<div>Son</div>
<slot></slot>
<slot></slot>
</template>
结果是:
具名插槽正确姿势
- 儿子组件的slot添加属性name='xxx'标记对应插槽的名称
- 父组件在儿子组件内部添加template标签,并添加#属性绑定对应儿子组件插槽的name值
Father.vue
<template>
<div>Father</div>
<Son>
<!--对应header插槽-->
<template #header>
<div>header</div>
</template>
<!--对应content插槽-->
<template #content>
<div>content</div>
</template>
<!--对应footer插槽-->
<template #footer>
<div>footer</div>
</template>
</Son>
</template>
Son.vue
<template>
<div>Son</div>
<slot name="header"></slot>
<slot name="content"></slot>
<slot name="footer"></slot>
</template>
结果:
根据结果分析知:具名插槽是有名称的,指定名称的插槽内容渲染到指定的插槽区域。
4.2 作用域插槽(插槽的传值)
作用域插槽研究的是:父组件的值如何通过插槽传递到儿子,儿子的值通过插槽如何传递给父亲。
父传子
插槽默认下,父组件的值可以直接通过插槽传递给儿子。十分方便
Father.vue
<template>
<div>Father</div>
<Son>
<template #header>
<div>{{age}}</div>
</template>
</Son>
</template>
<script lang='ts' setup>
import Son from "@/views/home/components/Son.vue"
import {ref} from "vue"
const age = ref(22)
</script>
Son.vue
<template>
<div>Son</div>
<slot name="header"></slot>
</template>
结果:
结论:父组件可以直接将数据通过插槽传递给儿子使用
子传父
父组件无法直接获取到儿子组件插槽定义的数据,必须通过指定方法完成。
子传父步骤:
-
儿子组件直接在插槽slot上定义数据
<slot age=22></slot>
-
父亲在儿子插槽上任意定义数据获取传递的数据
//如果是匿名插槽,匿名插槽本质上名称是default,info不是固定的,随便命名 <Son #default='info'> {{info.age}} </Son> //如果是具名插槽,具名插槽是通过template标签包裹,info不是固定的,随便命名 <Son> <template #name='info'> {{info.age}} <template/> </Son>
实例1
Father.vue
<template>
<div>Father</div>
<Son>
<!--匿名插槽-->
<template #default='info1'>
<div>默认插槽的数据{{info1.age}}</div>
</template>
<!--有名插槽-->
<template #header='info2'>
<div>header插槽的数据{{info2.age}}</div>
</template>
</Son>
</template>
Son.vue
<template>
<div>Son</div>
<slot age=22></slot>
<slot name='header' age=23></slot>
</template>
结果展示:
这个是匿名插槽和有名插槽的混合,二者子组件的插槽传递给各自的父组件。