vue3 插槽slot

插槽是子组件中的提供给父组件使用的一个占位符,用 <slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot> 元素。<slot> 元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。

一、匿名插槽 

子组件 FancyButton 中插槽模板

# 基础用法
<button class="fancy-btn"><!-- 插槽出口 --><slot></slot> 
</button># 可指定默认插槽内容:父组件没有提供任何插槽内容时,默认渲染的插槽内容 Submit
<button class="fancy-btn"><slot>Submit</slot> 
</button>

父组件填充插槽内容

<FancyButton><!-- 插槽内容 --><div>Click me!</div>
</FancyButton># 或<FancyButton><!-- 插槽内容 --><template v-slot><div>Click Me</div></template>
</FancyButton>

最终渲染出的 DOM 结构如下

<button class="fancy-btn">Click me!</button>

ps. 

通过使用插槽,使组件更加灵活和具有可复用性。这样组件可以用在不同的地方渲染各异的内容,但同时还保证都具有相同的样式。

二、具名插槽 (named slots) 

具名插槽其实就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。

对于这种场景,<slot> 元素可以有一个特殊的属性 name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容:

子组件预留的插槽

<div class="container"><header><slot name="header"></slot></header><main><-- 没有提供 name 的 slot 出口会隐式地命名为 “default” --><slot></slot></main><footer><slot name="footer"></slot></footer>
</div>

 父组件对指定插槽进行填充

要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令。

<BaseLayout><template v-slot:header><div>header</div></template><template v-slot><div>default</div></template><template v-slot:footer><div>footer</div></template>
</BaseLayout>

v-slot 语法糖(简写方式)

v-slot 有对应的简写 #,因此 <template v-slot:header> 可以简写为 <template #header>。其意思就是“将这部分模板片段传入子组件的 header 插槽中”。

<BaseLayout><template #header><h1>Here might be a page title</h1></template><template #default><p>A paragraph for the main content.</p><p>And another one.</p></template><template #footer><p>Here's some contact info</p></template>
</BaseLayout># 或# 当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非 <template> 节点都被隐式地视为默认插槽的内容。所以上面也可以写成:
<BaseLayout><template #header><h1>Here might be a page title</h1></template><!-- 隐式的默认插槽 --><p>A paragraph for the main content.</p><p>And another one.</p><template #footer><p>Here's some contact info</p></template>
</BaseLayout>

现在 <template> 元素中的所有内容都将被传递到相应的插槽。最终渲染出的 HTML 如下:

<div class="container"><header><h1>Here might be a page title</h1></header><main><p>A paragraph for the main content.</p><p>And another one.</p></main><footer><p>Here's some contact info</p></footer>
</div>

三、动态插槽

动态指令参数在 v-slot 上也是有效的,即可以通过变量定义动态插槽名:

<script setup>import { ref } from "vue";const name = ref('header')
</script>
<template><base-layout><template v-slot:[name]><div>动态插槽</div></template><!-- 缩写为 --><template #[name]><div>动态插槽</div></template></base-layout>
</temppate>

四、作用域插槽

在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。可以使用属性绑定的方式向一个插槽的出口上传递数据,称为插槽 props 。

4.1 匿名插槽数据传递

子组件 MyComponent传递插槽 props

<div><slot :text="greetingMessage" :count="1"></slot>
</div>  

父组件接收插槽 props:默认插槽通过子组件标签上的 v-slot 指令,直接接收到了一个插槽 props 对象

<MyComponent v-slot="slotProps">{{ slotProps.text }} {{ slotProps.count }}
</MyComponent># 或 在 v-slot 中使用解构语法
<MyComponent v-slot="{ text, count }">{{ text }} {{ count }}
</MyComponent>

4.2 具名插槽数据传递

具名作用域插槽的工作方式也是类似的,插槽 props 可以作为 v-slot 指令的值被访问到:v-slot:name="slotProps"

<MyComponent><template #header="headerProps">{{ headerProps }}</template><template #default="defaultProps">{{ defaultProps }}</template><template #footer="footerProps">{{ footerProps }}</template>
</MyComponent>

4.3 作用域插槽应用场景:高级列表组件示例

你可能想问什么样的场景才适合用到作用域插槽,这里我们来看一个 <FancyList> 组件的例子。它会渲染一个列表,并同时会封装一些加载远端数据的逻辑、使用数据进行列表渲染、或者是像分页或无限滚动这样更进阶的功能。然而我们希望它能够保留足够的灵活性,将对单个列表元素内容和样式的控制权留给使用它的父组件。我们期望的用法可能是这样的:

<FancyList :api-url="url" :per-page="10"><template #item="{ body, username, likes }"><div class="item"><p>{{ body }}</p><p>by {{ username }} | {{ likes }} likes</p></div></template>
</FancyList>

在 <FancyList> 之中,我们可以多次渲染 <slot> 并每次都提供不同的数据 (注意我们这里使用了 v-bind 来传递插槽的 props):

<ul><li v-for="item in items"><slot name="item" v-bind="item"></slot></li>
</ul>

上面的 <FancyList> 案例同时封装了可重用的逻辑 (数据获取、分页等) 和视图输出,但也将部分视图输出通过作用域插槽交给了消费者组件来管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/284128.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】磁盘分区管理及挂载/永久挂载管理

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

Aegisub字幕入门篇

目录 中文文档 介绍 语法 fs 控制字体大小 fn 控制字体样式 ​编辑 滚动特效代码 淡入淡出代码 渐变代码 字体大小渐变 字体间距渐变 字体边缘模糊渐变 字体对齐方式渐变 字体的渐变色设置 竖向跑马灯制作&#xff0c;电影字幕片尾 文字抖动 批量设置特效样式 中…

系列五、DQL

一、DQL 1.1、概述 DQL的英文全称为&#xff1a;Data Query Language&#xff0c;中文意思为&#xff1a;数据查询语言&#xff0c;用大白话讲就是查询数据。对于大多数系统来说&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访问企业官网、电商网站&…

如何利用视频号爆款数据分析平台,实现播放变现?

利用视频号爆款数据分析平台了解当下视频号热点视频&#xff0c;以及那个分类更有潜力&#xff0c;可以即使进行预判&#xff0c; 变现是近年来非常流行的一种商业模式。视频号爆款数据分析平台是视频下载plus的一个功能&#xff0c;可以让用户通过每天都热点数据以及热门榜单…

【面试】Java最新面试题资深开发-微服务篇(1)

问题九&#xff1a;微服务 什么是微服务架构&#xff1f;它与单体架构相比有哪些优势和劣势&#xff1f;解释一下服务发现和服务注册是什么&#xff0c;它们在微服务中的作用是什么&#xff1f;什么是API网关&#xff08;API Gateway&#xff09;&#xff1f;在微服务中它有何…

LeetCode 每日一题 Day 13 || BFS

2415. 反转二叉树的奇数层 给你一棵 完美 二叉树的根节点 root &#xff0c;请你反转这棵树中每个 奇数 层的节点值。 例如&#xff0c;假设第 3 层的节点值是 [2,1,3,4,7,11,29,18] &#xff0c;那么反转后它应该变成 [18,29,11,7,4,3,1,2] 。 反转后&#xff0c;返回树的根…

redis:二、缓存击穿的定义、解决方案(互斥锁、逻辑过期)的优缺点和适用场景、面试回答模板和缓存雪崩

缓存击穿的定义 缓存击穿是一种现象&#xff0c;具体就是某一个数据过期时&#xff0c;恰好有大量的并发请求过来&#xff0c;这些并发的请求可能会瞬间把DB压垮。典型场景就是双十一等抢购活动中&#xff0c;首页广告页面的数据过期&#xff0c;此时刚好大量用户进行请求&…

springcloud:对象存储组件MinIO

类似于FastDFS/HDFS的一个文件存储服务&#xff01; SpringBoot整合MinIO实现分布式文件服务&#xff01; #MinIO简介&#xff1f; Minio 是个基于 Golang 编写的开源对象存储套件&#xff0c;基于Apache License v2.0开源协议&#xff0c;虽然轻量&#xff0c;却拥有着不错的…

什么是开放式耳机?骨传导耳机是开放式耳机吗?

一、什么是开放式耳机&#xff1f; 开放式耳机是一种无需入耳佩戴的蓝牙耳机&#xff0c;在佩戴上比传统入耳耳机更加稳固舒适&#xff0c;更适合运动场景佩戴&#xff0c;而且使用的时候不会隔绝周围环境声&#xff0c;可以时刻注意到周围的环境变化&#xff0c;使用更安全。…

PFA三口烧瓶本底纯净耐强酸实验室常用反应烧瓶

PFA&#xff08;聚氟乙烯&#xff09;三口烧瓶是一种在化学实验室中广泛使用的常规实验仪器&#xff0c;它具有许多优点&#xff0c;使其成为许多实验室中使用的首选容器。以下是PFA三口烧瓶的主要优点&#xff1a; 1. 高耐化学性&#xff1a;PFA三口烧瓶是由聚氟乙烯制成的&am…

触想智能工业一体机在金属3D打印机上的应用

1、行业发展背景 3D打印又称“增材制造”&#xff0c;是一种以数字模型为基础&#xff0c;通过逐层堆叠将打印材料熔结固化为三维实体物件的先进制造技术。 随着航空航天、科研、医疗、汽车等精工领域的颠覆性发展&#xff0c;制造业对于高强度、高精度、轻量型、柔性化金属零件…

NFTScan | 12.11~12.17 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2023.12.11~ 2023.12.17 NFT Hot News 01/ Pudgy Penguins 衍生 NFT Lil Pudgys 过去一天成交量超 1000 枚 ETH&#xff0c;位居第二 12 月 11 日&#xff0c;据 OpenSea 数据显示&#…