uniapp插槽用法

目录

什么是插槽?

基本概念

默认插槽

命名插槽

作用域插槽

场景一:子插槽向父组件传递一个字符串

场景二:子插槽向父组件传递对象


什么是插槽?

在 UniApp 中,插槽(Slot)是一种允许父组件向子组件特定位置插入HTML内容的方式。这种方式使得组件更加灵活,可以被复用在多种场景下,同时让父组件能够控制子组件的部分呈现内容。

基本概念

  1. 默认插槽:当没有特别指定插槽名称时,默认插槽就是指没有名字的插槽,可以在子组件中直接使用 <slot></slot> 标签来定义一个默认插槽的位置。

  2. 命名插槽:如果需要在子组件中定义多个插槽,可以通过 <slot name="slotName"></slot> 来定义具有特定名称的插槽。父组件则需要使用 <template v-slot:slotName>...</template> 或者更简洁的 <template #slotName>...</template> 来填充这些具名插槽。

  3. 作用域插槽:有时候父组件需要访问子组件的数据或属性,这时候就需要使用作用域插槽。子组件需要在 <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的响应式函数ref
	import {
		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}}&nbsp;{{item.age}}
			</view>
		</template>
	</bdqn-header>
</template>

执行的结果

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值