目录
什么是插槽?
基本概念
默认插槽
命名插槽
作用域插槽
场景一:子插槽向父组件传递一个字符串
场景二:子插槽向父组件传递对象
什么是插槽?
在 UniApp 中,插槽(Slot)是一种允许父组件向子组件特定位置插入HTML内容的方式。这种方式使得组件更加灵活,可以被复用在多种场景下,同时让父组件能够控制子组件的部分呈现内容。
基本概念
默认插槽:当没有特别指定插槽名称时,默认插槽就是指没有名字的插槽,可以在子组件中直接使用
<slot></slot>
标签来定义一个默认插槽的位置。命名插槽:如果需要在子组件中定义多个插槽,可以通过
<slot name="slotName"></slot>
来定义具有特定名称的插槽。父组件则需要使用<template v-slot:slotName>...</template>
或者更简洁的<template #slotName>...</template>
来填充这些具名插槽。作用域插槽:有时候父组件需要访问子组件的数据或属性,这时候就需要使用作用域插槽。子组件需要在
<slot>
标签中声明需要传递给父组件的数据,如<slot name="slotName" :items="items"></slot>
。父组件在使用这个插槽时,可以通过v-slot:slotName="{ items }"
来接收这些数据,并根据这些数据进行渲染。
默认插槽
子插槽:
<slot>
元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。<template><view class="all"><view class="header">头部</view><view class="main"><slot></slot></view><view class="footer">底部</view></view> </template><script setup></script><style lang="scss" scoped>.header {position: sticky;top: 0;background-color: green;height: 100px;z-index: 1; // 确保头部始终在最上层}.main {height: 100px;}.footer {background-color: rosybrown;height: 120px;} </style>
父组件:可以通过调用直接在组件内部编写代码,只适合一个插槽的场景
<template><bdqn-header>661</bdqn-header> </template><script setup></script><style scoped lang="scss"></style>
命名插槽
子插槽:定义了多个插槽,会导致什么问题呢???
<template><view class="all"><view class="header"><slot></slot></view><view class="main"><slot></slot></view><view class="footer"><slot></slot></view></view> </template>
当出现多个插槽的时候会导致插入的时候,会在每个插槽都插入相同的数据
<template><bdqn-header>661</bdqn-header> </template>
调用插槽后会导致多个相同结构,使一个结构体重复出现多次
那么如何解决呢? 这个时候就可以用到命名插槽,在插槽标签slot中添加name属性,在调用的时候使用v-slot:名称来指定插槽插入,这样就可以避免一次性调用多个插槽,也可以简写为 #名称
<template><view class="all"><view class="header"><slot name="header"></slot></view><view class="main"><slot name="main"></slot></view><view class="footer"><slot name="footerK"></slot></view></view> </template>
调用子插槽的时候 通过添加 v-slot:名称 来指定插槽的位置
<template><bdqn-header><template v-slot:header>头部</template><template v-slot:main>主体</template><template v-slot:footerK>尾部</template></bdqn-header> </template><template><bdqn-header><template #header>头部</template><template #main>主体</template><template #footerK>尾部</template></bdqn-header> </template>
效果图:可以看见这样子就可以实现分别给多个插槽编写不同的实现代码
作用域插槽
作用域插槽就是可以让子插槽和父组件相互传值,相互访问
场景一:子插槽向父组件传递一个字符串
子插槽:通过name指定插槽的名称,定义一个text的变量并赋值 ( 语法 变量=值 )
<template><view class="all"><view class="header"><slot name="header" text="头部:我是一个字符串"></slot></view><view class="main"><view><!-- 定义一个作用域插槽,并传递数据 --><slot name="main" text="局部:我是一个字符串"></slot></view></view><view class="footer">底部</view></view> </template>
父组件:
- 通过
v-slot:header="{ text }"
定义了一个名为header
的作用域插槽。text
是从子组件传递过来的数据。- 在模板中通过
{{ text }}
显示传递过来的文本。<template><!-- 使用自定义组件 bdqn-header,并为其定义两个作用域插槽:header 和 main --><bdqn-header><!-- 定义 header 作用域插槽,并访问子组件传递的 text 数据 --><template v-slot:header="{ text }"><view>{{ text }}</view></template><!-- 定义 main 作用域插槽,并访问子组件传递的 text 数据 --><template v-slot:main="{ text }"><view>{{ text }}</view></template></bdqn-header> </template>
运行效果
场景二:子插槽向父组件传递对象
子插槽:向父组件传递了一个items对象( 语法 :名称="传递的对象" )
<template><view class="all"><!-- 头部区域 --><view class="header"><!-- 使用插槽传递头部内容,提供默认文本 --><slot name="header" text="头部:我是一个字符串"></slot></view><!-- 主要内容区域 --><view class="main"><!-- 包裹一个view以便于统一管理插槽内容 --><slot name="main" :items="items"></slot></view><!-- 底部区域,直接输出底部内容 --><view class="footer">底部</view></view> </template><script setup>// 导入Vue的响应式函数refimport {ref} from 'vue';// 定义一个响应式的items数组,包含姓名和年龄信息var items = ref([{name: '张三',age: 18}, {name: '李四',age: 19}, {name: '王五',age: 25}]) </script><style lang="scss" scoped>.header {position: sticky;top: 0;background-color: green;height: 100px;z-index: 1; // 确保头部始终在最上层}.main {height: 100px;}.footer {background-color: rosybrown;height: 120px;} </style>
父组件: 通过插槽接收子插槽传递的对象 ( 语法 #main="{items}" )
- 通过
#main
插槽展示列表项。- #main表示插槽指定的名称(name名称)
- "{items}" 表示传递的对象,使用{}包裹
<template><!-- 使用自定义组件bdqn-header来构建页面布局 --><bdqn-header><!-- 通过header插槽自定义头部内容 --><template v-slot:header="{ text }"><view>{{ text }}</view></template><!-- 通过main插槽展示主体内容,通常用于列表展示 --><template #main="{items}"><view v-for="item in items">{{item.name}} {{item.age}}</view></template></bdqn-header> </template>
执行的结果