Vue3-slot

news/2025/1/23 10:28:01/文章来源:https://www.cnblogs.com/dragon-925/p/18292134

描述

      为了能在当前组件中使用其他组件中的内容,并且可以改变其他组件中的内容结构。使用的技术就叫做“插槽”
      在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。举例:

  • 子组件<FancyButton/>

    <template><button class="fancy-btn"><slot/> <!-- slot outlet --></button>
    </template><style>
    .fancy-btn {color: #fff;background: linear-gradient(315deg, #42d392 25%, #647eff);border: none;padding: 5px 10px;margin: 5px;border-radius: 8px;cursor: pointer;
    }
    </style>
    
  • 父组件

    <script setup>
    import FancyButton from './FancyButton.vue'
    </script><template><FancyButton><h2>打开</h2> <!-- slot content --></FancyButton>
    </template>
    
  • 效果图

这就是在App组件显示的内容。
<slot> 元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。

默认插槽

在外部没有提供任何内容的情况下,可以为插槽指定默认内容。比如有这样一个 组件:

<button type="submit"><slot></slot>
</button>

如果我们想在父组件没有提供任何插槽内容时在 <button> 内渲染“Submit”,只需要将“Submit”写在 标签之间来作为默认内容:

<button type="submit"><slot>Submit <!-- 默认内容 --></slot>
</button>

现在,当我们在父组件中使用 且没有提供任何插槽内容时:

<SubmitButton />

“Submit”将会被作为默认内容渲染:

<button type="submit">Submit</button>

但如果我们提供了插槽内容:

<SubmitButton>Save</SubmitButton>

那么被显式提供的内容会取代默认内容:

<button type="submit">Save</button>

具名插槽

有时在一个组件中包含多个插槽出口是很有用的。举例来说,在一个 <BaseLayout> 组件中,有如下模板:

<div class="container"><header><!-- 标题内容放这里 --></header><main><!-- 主要内容放这里 --></main><footer><!-- 底部内容放这里 --></footer>
</div>

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

<div class="container"><header><slot name="header"></slot></header><main><slot></slot></main><footer><slot name="footer"></slot></footer>
</div>

这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 <slot> 出口会隐式地命名为“default”。

在父组件中使用 <BaseLayout> 时,我们需要一种方式将多个插槽内容传入到各自目标插槽的出口。此时就需要用到具名插槽了:

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

<BaseLayout><template v-slot:header><!-- header 插槽的内容放这里 --></template>
</BaseLayout>

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

具名插槽图示

下面我们给出完整的、向 <BaseLayout> 传递插槽内容的代码,指令均使用的是缩写形式:

<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>

作用域插槽

插槽的内容无法访问到子组件的状态。

然而在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。

我们也确实有办法这么做!可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes:

<!-- <MyComponent> 的模板 -->
<div><slot :text="greetingMessage" :count="1"></slot>
</div>

当需要接收插槽 props 时,默认插槽和具名插槽的使用方式有一些小区别。下面我们将先展示默认插槽如何接受 props,通过子组件标签上的 v-slot 指令,直接接收到了一个插槽 props 对象:

<MyComponent v-slot="slotProps">{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>

具名作用域插槽

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

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

向具名插槽中传入 props

<slot name="header" message="hello"></slot>

注意插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽。因此最终 headerProps 的结果是 { message: 'hello' }

如果你同时使用了具名插槽与默认插槽,则需要为默认插槽使用显式的 <template> 标签。尝试直接为组件添加 v-slot 指令将导致编译错误。这是为了避免因默认插槽的 props 的作用域而困惑。举例:

<!-- <MyComponent> template -->
<div><slot :message="hello"></slot><slot name="footer" />
</div>
<!-- 该模板无法编译 -->
<MyComponent v-slot="{ message }"><p>{{ message }}</p><template #footer><!-- message 属于默认插槽,此处不可用 --><p>{{ message }}</p></template>
</MyComponent>

为默认插槽使用显式的 <template> 标签有助于更清晰地指出 message 属性在其他插槽中不可用:

<MyComponent><!-- 使用显式的默认插槽 --><template #default="{ message }"><p>{{ message }}</p></template><template #footer><p>Here's some contact info</p></template>
</MyComponent>

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

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

相关文章

FPGA bit转bin文件

首先科普一下 什么是bitstream文件 FPGA比特流(bitstream)是一种用于配置可编程逻辑器件的数据格式,特别是现场可编程门阵列(FPGA)。比特流包含了硬件逻辑电路、路由信息以及芯片上寄存器和存储器(如查找表LUT)的初始值。通常认为比特流具有厂商特定的格式,因此很难反向…

mysql集群高可用架构MHA

一、MHA概述 1.为什么要用MHA Master的单点故障问题 2.什么是 MHA MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。MHA 的出现就是解决MySQL 单点的问题。MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。MHA能在故障切…

coca 经常过期

re-doHELP ADD NOTE DELETERE-DOSHARE LINKCORPUSWORD(S)SECTIONSTYPEWHENELAPSED (MS) 1COCAliable for + *COLL7/7/2024754

Git Commit 提交规范

背景 Git每次提交代码都需要写commit message,否则就不允许提交。一般来说,commit message应该清晰明了,说明本次提交的目的,具体做了什么操作。但是在日常开发中,大家的commit message千奇百怪,中英文混合使用、fix bug等各种笼统的message司空见怪,这就导致后续代码维…

docker-compose创建haproxy教程

本文主要讲解通过docker-compose创建haproxy并进行代理 一、haproxy简介HAProxy是一款基于事件驱动、单进程模型设计的四层与七层负载均衡器,它能够在TCP/UDP层面以及HTTP(S)等应用层协议上实现高效的流量分发。HAProxy不仅适用于Web服务器负载均衡,还能应用于数据库、邮件服…

Pytorch实现基于MNIST的手写数字识别

本文目的在于训练一个模型,使其能对手写的数字图片进行分类识别,并不断优化使其准确度尽可能地提高 一、数据预处理 (1)运行时所需库 import numpy as np import torch import torchvision from torch import nn from torch.utils.data import DataLoader from t…

【proto】python根据proto文件构造message,并换为二进制

一、场景测试需要构造数据,而且存储的格式为grpc消息的二进制格式,所以必须要根据proto构造二进制二、构造方法 1、根据proto文件生成python格式的pb文件python3 -m grpc_tools.protoc -I. proto/upload_state.proto --python_out=. --grpc_python_out=. 2、检查文件生成 3…

electron 跨域/CSP问题

请求报错:Refused to connect to http://127.0.0.1:8000/get?name=kv-grpc because it violates the following Content Security Policy directive: "default-src self". Note that connect-src was not explicitly set, so default-src is used as a fallback 这…

松灵机器人scout mini小车 自主导航(2)——仿真指南

松灵机器人Scout mini小车仿真指南 之前介绍了如何通过CAN TO USB串口实现用键盘控制小车移动。但是一直用小车测试缺乏安全性。而松灵官方贴心的为我们准备了gazebo仿真环境,提供了完整的仿真支持库,本文将介绍如何上手使用仿真。 官方仓库地址:https://github.com/agilexr…

zabbix“专家坐诊”第245期问答

问题一 Q:vfs.dev.discovery拿的是哪里的文件,我看源码里面获取的是/proc/parttions里面的信息,但是我没有这个device,是怎么获取出来的?A:检查下系统内核版本或者agent程序版本,如果未定义KERNEL_2_4的情况下,读的是后面这个文件。 Q:这两个文件我都看过,也没有cdro…

【Python】Word文档操作

一、全文替换 不是创建word文档写入内容,而是基于现有的Word文档进行替换处理 使用run.text直接赋值修改发现样式会丢失,而网上大部分办法都是这么写的... 直到我看到这篇文章的评论:https://blog.csdn.net/qq_40222956/article/details/106098464 除了段落替换后,Word文档…

【ubuntu】安装go

一、官网 https://golang.google.cn/dl/ 选择稳定版本,点击下载二、安装步骤 1、解压2、移动目录sudo mv go /usr/local3、配置环境变量 vim ~/.bashrcexport PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/gocode创建gocode目录 vim ~/.profile 添加同样配置三、验证$ g…