slot插槽
Vue 实现了一套内容分发的 API,将 元素作为承载分发内容的出口
简单理解:就是对子组件的扩展,通过 插槽向子组件内部指定位置传递内容
插槽是组件的一块HTML模板,这块模板显示不显示,怎样显示是由父组件来控制的,而插槽在哪里显 示就由子组件来进行控制。
与props的不同:
- 通过props属性,父组件只能向子组件传递属性、方法
- 而插槽还可以传递带标签的内容、甚至是组件等,更灵活
slot.vue:
<template>
<div>
hello slot
<!--如果不给插槽填充内容,则显示默认内容;填充内容,默认内容部生效-->
<slot>默认内容</slot>
</div>
</template>
<script setup>
</script>
<style scoped></style>
home.vue:
<template>
<Slot>
<!--匿名插槽-->
<button>点击</button>
<div>
<ul>
<li>111111</li>
<li>222222</li>
</ul>
</div>
</Slot>
</template>
<script setup>
import Slot from './slot.vue'
</script>
<style scoped></style>
插槽类型
插槽分为:匿名插槽| 具名插槽| 作用域插槽
匿名插槽
sub.vue:
<template>
<div>
<slot></slot>
</div>
</template>
<script setup>
</script>
<style scoped></style>
home.vue:
<Sub>
<!--slot可以省略,有没有slot都是匿名插槽-->
<ul slot>
<li v-for="(v, i) in arr" :key="i">{
{ v }}</li>
</ul>
</Sub>
具名插槽
插槽加了名称属性,就变成了具名插槽。在 v-slot 之后添加冒号 (:) ,然后写出要传递内容的 slot 的名称
<!--具名插槽-->
<slot name="header"></slot>
hello world
<button>click</button>
<slot name="xyz"></slot>
<slot></slot>
<Sub>
<template #header>
<h1>ABC</h1>
</template>
<template #xyz>
<ul>
<li v-for="(v, i) in arr" :key="i">{
{ v }}</li>
</ul>
</template>
<!--我们指定了 default 的名称,表示不需要为默认插槽指定名称-->
<template #default>
<button>default</button>
</template>
</Sub>
作用域插槽
官方叫它作用域插槽,实际上,对比前面两种插槽,我们可以叫它带数据的插槽
作用域插槽跟单个插槽和具名插槽的区别,因为单个插槽和具名插槽不绑定数据,所以父组件提供的模板一般要既包括样式又包括内容, 而作用域插槽,相当于父组件提供一套样式,数据都是子组件的。
Sub.vue:
<template>
<div>
<!--数据插槽,也是作用域插槽-->
<slot name="header" :user="user" :num="n">
</slot>
</div>
</template>
<script setup>
import { ref } from 'vue'
const user = ref({ title: 'title', name: 'jack' })
let n = ref(10);
</script>
<style scoped></style>
home.vue:
<!--作用域插槽:obj可以随便定义,这的obj是一个大对象,插槽数据在这个大对象里-->
<Sub>
<template #header="obj">
<h1>标题:{
{ obj.user.title }}</h1>
<h1>作者:{
{ obj.user.name }}</h1>
</template>
</Sub>
<!--插槽数据对象解构-->
<Sub>
<template #header="{ user }">
<h1>标题:{
{ user.title }}</h1>
<h1>作者:{
{ user.name }}</h1>
</templa