Vue 中 slot 是什么?作用?分类?如何实现?

结论先行:

slot 插槽,是子组件提供给父组件使用的一个占位符,父组件可以在这个占位符中填充任何模板代码。主要作用就是更好的拓展和定制化组件,例如弹窗组件、表格组件等。分为默认插槽、具名插槽和作用域插槽。

其中前两个都是渲染在父级,本质上就是替换,父组件渲染完毕之后替换对应的 slot;区别在于具名插槽就是给插槽取了名字;

而作用域插槽在组件内部渲染。本质上会把父组件的内容渲染成函数,子组件调用函数,并且将数据传递给它。当需要将子组件的数据交给父组件展示,此时就可以使用作用域插槽。给数据一个新的作用域,因此叫做作用域插槽。 

应用场景:自定义的表格组件,允许用户传入自定义的结构 + 数据(从插槽中回传的)

1、什么是 slot ? 

① 官方文档 

官方文档 Vue2:插槽 — Vue.js

官方文档 Vue3:插槽 Slots | Vue.js 

② 概念 

slot(插槽)是一种用于分发内容的机制,一种用于在组件中传递内容的机制

也就是说在组件模板中利用 slot 进行占位,然后在使用组件时,传入的组件内容也就是 HTML 片段,会分发的对应的 slot 中。 

它允许你在组件的模板中定义带有特殊标记的区域,然后在使用该组件时填充这些区域。

通过 <slot></slot> 标签来定义一个插槽。这个插槽可以有默认内容,也可以是没有任何内容的。当使用该组件时,可以将内容插入到插槽中。

插槽可以有默认值,直接在 slot 里设置。

简单理解就是子组件中留下个“坑”,父组件可以使用指定内容来补“坑”。以下是一个简单的示例,展示了如何在 Vue 组件中使用插槽:

<!-- 父组件 -->
<template>
  <div>
    <h1>父组件</h1>
    <ChildComponent>
      <p>这是插入到子组件中的内容</p>
    </ChildComponent>
  </div>
</template>

<!-- 子组件 -->
<template>
  <div>
    <h2>子组件</h2>
    <!-- 这里是插槽 -->
    <slot></slot>
  </div>
</template>

在上面的示例中,父组件中的 <ChildComponent> 标签包含了一个 <p> 标签,作为插入到子组件中的内容。子组件中的 <slot></slot> 标签表示一个插槽,它将会被父组件中的内容所填充。

③ 内容定义方式 

在 Vue2.6.0 之后,使用 v-slot 或者语法糖 #插槽名 定义;在这之前使用 slot="插槽名" 定义。 

跟 v-on 和 v-bind 一样,v-slot 也有缩写,也就是把参数之前的所有内容 (v-slot:) 替换为字符 #

下面是三种 默认插槽 的内容定义方式,并且最后一个默认插槽的内容会覆盖掉上一个插槽内容 

使用 template 包裹内容,同时使用 v-slot 绑定一个名称。  

v-slot 一般跟 template 标签使用 (template 是 html5 新出的标签内容模板元素,不会渲染到页面上, 一般被 vue 解析为内部标签)

<child>
  <template>
    <span style="color: red">这里是默认插槽内容1,字体为红色</span>
  </template>

  <template v-slot:default>
    <span style="color: yellow">这里是默认插槽内容2,字体为h黄色</span>
  </template>

  <template #default>
    <span style="color: blue">这里是默认插槽内容3,字体为蓝色</span>
  </template>
</child>
④ 独占默认插槽的缩写  

v-slot:default="slotProps" 可以简写为 v-slot="slotProps"

如果我们的插槽只有默认插槽时,组件的标签可以被当做插槽的模板来使用。

也就是可以将 v-slot 直接用在组件上

2、插槽的作用 ? 

通过使用插槽,我们可以实现更加灵活和可复用的组件,增强组件的可复用性。

当一个组件需要接收外部传入的内容时,可以使用插槽来实现这个功能。

同时,插槽还可以指定默认内容,当没有提供具体内容时将显示默认内容。 

通过插槽可以让用户更好的对组件进行拓展和定制化,可以通过具名插槽指定渲染的位置。

常用的组件例如:弹窗组件、布局组件、表格组件……

3、插槽的分类 

① 默认插槽

不指定插槽 name 属性。也就是插槽的内容出口(不写名字出口会带有隐含的名字“default”)

  • 默认插槽是指在父组件中没有提供具名插槽名称的情况下使用的插槽。父组件中未匹配到具名插槽的内容会被放置在默认插槽中。
  • 在 Vue 2 中,默认插槽是不带任何属性的 <slot> 元素。
  • 在 Vue 3 中,默认插槽使用 v-slot 指令来定义。

<slot name="default"></slot>   或者  <slot></slot>

<!-- 父组件 -->
<template>
  <div>
    <h1>父组件</h1>
    <ChildComponent>
      <p>这是插入到子组件中的内容</p>
    </ChildComponent>
  </div>
</template>

<!-- 子组件 -->
<template>
  <div>
    <h2>子组件</h2>
    <!-- 这里是插槽 -->
    <slot></slot>
  </div>
</template>
② 具名插槽

渲染在父级(父组件渲染好了,子组件根据 slot 对应的名字来替换就可以);

本质上就是替换,普通插槽就是在父组件渲染完毕之后,使用子组件替换掉父组件的占位符 slot;

定义: <slot name="xxx">

使用:

  • <template #xxx></template>;
  • <template v-slot:xxx></template>
  • 具名插槽允许子组件将内容分发到父组件中指定名称的插槽上。
  • 在 Vue 2 中,可以通过给 <slot> 元素添加 name 属性来创建具名插槽,然后在父组件中使用 <template v-slot:slotName> 或者 <slot name="slotName"> 来引用具名插槽。
  • 在 Vue 3 中,具名插槽被称为命名插槽,可以使用新的 v-slot 指令来定义。
<!-- 子组件 -->
<div>
    <!-- 具名插槽:指定了name属性, 内容出口 -->
    <slot name="name-1"></slot>
</div>


<!-- 父组件 -->
<child>
<template v-slot:name-1="slotProps">
    <span style="color: red">
        {{ slotProps.user.firstName }}
        这里是具名插槽内容1,字体为红色
    </span>
</template>

<template #name-1="{ user }">
    <span style="color: yellow">
        {{ user.firstName }}
        这里是具名插槽内容2,字体为黄色
    </span>
</template>
</child>

下面是两种 具名插槽 的内容定义方式,并且最后一个插槽的内容会覆盖掉上一个插槽内容。

注意:默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确

③ 作用域插槽

作用域插槽:把组件内的值取出来自定义显示内容。 

作用域插槽在组件内部渲染。本质上会把父组件的内容渲染成函数,子组件调用函数,并且将数据传递给它。函数的返回值就会替换掉这个占位符。

  • 作用域插槽允许子组件将数据传递到父组件中的插槽内容中,使得父组件可以使用子组件中的数据进行渲染。
  • 在 Vue2 中,作用域插槽通过 <slot> 元素的 name 属性以及 <template slot-scope="props"> 来实现。
  • 在 Vue 3 中,作用域插槽的语法发生了变化,使用 v-slot 指令和新的 # 符号来指定插槽的作用域

组件内变量绑定在 slot 上,然后使用组件 v-slot:插槽名字="变量" ,变量上就会绑定 slot 传递的属性和值,插槽可以自定义显示内容;

运用场景:自定义的表格组件,允许用户传入:自定义的结构 + 数据(从插槽中回传的)

scope:是我指定的作用域这个作用域是插槽的作用域。可以获取插槽上除 name 属性外的其他自定义属性,来获取到插槽上的数据

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

<!-- 子组件 -->
<div>
    <slot name="name-1" slotMessage="信息1" slotMessage2="信息2"></slot>
</div>

<!-- 父组件 -->
<child>
    <template #name-1="scope">
        <!-- 下面这些值将会展示到插槽出口位置 -->
        <span>{{ scope }}</span><br>
        <span>{{ scope.slotMessage1 }}</span><br>
        <span>{{ scope.slotMessage2 }}</span><br>
    </template>
</child>

当需要将子组件的数据交给父组件展示,此时就可以使用作用域插槽。在子组件中,在 slot 中使用v-bind 绑定需要传递的数据 

<slot :testProps="list">插槽后备内容</slot> 

//在父组件中的子组件名中使用v-slot="属性名"的方式接受 
<Child> 
    <template v-slot="testProps"> 
        <p v-for="item in testProps" :key="item.id"> {{ item.name }} </p> 
    </template>
</Child>

4、动态插槽名 

 目前我们使用的插槽名称都是固定的,比如 v-slot:left、v-slot:center 等等;

我们可以通过 v-slot:[dynamicSlotName] 方式动态绑定一个名称;

4、Vue2 和 Vue3 的区别

① 都能使用 v-slot:name 或者其缩写 #name 的方式来定义具名插槽;

② 如果在父组件中传入多个插槽内容,那 Vue2 总是会展示最后一个插槽的内容,Vue3 会展示第一个插槽内容。

③ 作用域插槽,Vue2.x 的机制导致作用域插槽变了,父组件会重新渲染。而 Vue3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能

5、总结

① v-slot 属性只能在 <template> 上使用,但在只有默认插槽时可以在组件标签上使用;

② 默认插槽名为 default,可以省略 default 直接写v-slot;

③ 缩写为 时不能不写参数,写成 #default

④ 可以通过解构获取 v-slot={user},还可以重命名 v-slot="{user: newName}" 和定义默认值 v-slot="{user = '默认值'}"

在Vue中有渲染作用域的概念:

  • 父级模板里的所有内容都是在父级作用域中编译的
  • 子模板里的所有内容都是在子作用域中编译的

  • 组件 ChildCpn 中,可以拿到自己作用域中的 title 内容;
  • 但是在 App 中,是访问不了 ChildCpn 中的内容的,因为它们是跨作用域的访问;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM系列 | 27 : 天工大模型Skywork解读及揭露刷榜内幕引发的思考

引言 简介 预训练 ​语料 分词器 模型架构 Infrastructure 训练细节 评测 实战 总结 思考 0. 引言 晨起开门雪满山&#xff0c;雪晴云淡日光寒。 Created by DALLE 3 小伙伴们好&#xff0c;我是《小窗幽记机器学习》的小编&#xff1a;卖热干面的小女孩。紧接前…

ATECLOUD-POWER电源测试系统有什么特点?如何用它测试电源模块?

ATECLOUD-POWER电源测试系统 ATECLOUD-POWER是检测电源性能的自动化测试系统&#xff0c;针对电源模块各类测试项目提供定制方案&#xff0c;指导电源模块的设计和生产&#xff0c;保证电源的质量、稳定性和可靠性。该方案包括软件定制开发以及硬件设备选择两方面&#xff0c;根…

idea启动类运行后报错:Port 6380 was already in use.

问题原因&#xff1a; idea窗口中某个项目还在启动中时 误关了窗口&#xff0c;导致在其他项目运行时报错端口被占用 解决办法&#xff1a; 先杀掉占用端口&#xff0c;再重新启动 步骤如下&#xff1a; 1.先找到6380端口对应pid winr打开cmd命令行窗口 输入命令&#xf…

web缓存-----squid代理服务

squid相关知识 1 squid的概念 Squid服务器缓存频繁要求网页、媒体文件和其它加速回答时间并减少带宽堵塞的内容。 Squid代理服务器&#xff08;Squid proxy server&#xff09;一般和原始文件一起安装在单独服务器而不是网络服务器上。Squid通过追踪网络中的对象运用起作用。…

记录一次hibernate3.1 方言问题

错误&#xff1a;com.sun.proxy.$Proxy553 cannot be cast to java.lang.string 我们项目上&#xff0c;将mysql数据库迁移到达梦数据库&#xff0c;这样会造成数据库类型上在java查询下&#xff0c;会有不兼容的问题&#xff0c;比如clob&#xff0c;text等&#xff0c;…

node服务部署vue3(ssr)单页面应用上线

博主最新开发了vue3新版的单页面服务端渲染的博客&#xff0c;框架用的vue3框架&#xff0c;vite4构建&#xff0c;在部署上线的时候遇到了一些问题&#xff0c;现在分享给大家。避免踩坑 node环境搭建 node安装包下载 因为我的服务器系统是linux&#xff0c;所以选择linux版本…

【技术分享】配置二层远程端口镜像案例

热门IT课程-CSDN博客文章浏览阅读24次。认证课程介绍&#xff1a;华为HCIA试听课程 &#xff1a; 华为HCIA试听课程&#xff1a;华为HCIA试听课程&#xff1a;华为HCIP试听课程&#xff1a;思科CCNA试听课程&#xff1a;思科CCNA试听课程&#xff1a;思科CCNA试听课程&#xff…

自动驾驶汽车:人工智能最具挑战性的任务

据说&#xff0c;自动驾驶汽车是汽车行业梦寐以求的状态&#xff0c;将彻底改变交通运输业。就在几年前&#xff0c;对自动驾驶汽车的炒作风靡一时&#xff0c;那么到底发生了什么呢&#xff1f;这么多公司吹嘘到2021年我们将迎来的无人驾驶汽车革命在何处&#xff1f;事实证明…

科研学习|研究方法——案例研究设计与方法

作者&#xff1a;罗伯特K.殷 &#xff08;一&#xff09;计划&#xff1a;如何把握何处、何时用案例研究方法 1.问题&#xff1a; 按照作者的观点&#xff0c;案例研究1984年之后才逐渐得到重视&#xff0c;可是在数据信息有效收集的时代&#xff0c;几乎所有的经典都是以案例…

C# 之 选择并调用文件[winform]

winform 之 选择并调用文件 在 form.cs[设计] 文件中选择一个button, 然后设置一个点击函数 将下方内容复制到函数中执行 private void push_btn_Click(object sender, EventArgs e){ // 1. 打开文件管理器选择文件OpenFileDialog openFileDialog1 new OpenFileDialog(); /…

一家公司做了两年软件测试,只会功能测试,现在已经感到危机感了,那如何摆脱困境呢?

经常听到一些行业内的朋友说 “做测试&#xff0c;有手就行” 但事实真的是如此嘛&#xff1f; 随着测试行业的发展&#xff0c;越来越多的测试岗位对自动化测试&#xff0c;性能测试都有所要求&#xff0c;这对于很多只会功能测试的职场老人们来说&#xff0c;有了一丝丝的…

【java学习—十四】java动态代理(6)

文章目录 1. 相关概念2. 步骤3. 举例 问题&#xff1a; 假设一个java项目有100个java类&#xff0c;每个java有10个方法&#xff0c;这总共有1000个方法&#xff0c;现在有这样一个需求&#xff0c;需要在每个java方法加上2句话&#xff1a;在方法执行前输出这个方法开始执行&a…

App Inventor 2 如何比较两个日期/时间?

利用计时器组件的相关方法&#xff1a; 比较两个日期/时间对象的毫秒数&#xff0c;具体请参见文档&#xff1a;https://www.fun123.cn/reference/ ... tml#Clock.GetMillis

QT使用Socket与安卓Socket互发消息

背景:安卓设备通过usb网络共享给Linux,此时安卓设备与linux处于同一网络环境,符合使用socket的条件,linux做客户端,安卓做服务端 1.QT使用Socket (1).在工程文件中加入 QT network (2).导包以及写一些槽函数用做数据传输与状态接收 #ifndef MAINWINDOW_H #define MAINWINDOW…

利用自动化和条形码优化SAP制造供应链

背景 Welch Allyn 是全球领先的医疗诊断设备制造商&#xff0c;开发了数百种突破性产品和技术&#xff0c;使一线从业者能够提供卓越的患者护理。它拥有近 2,500 名员工&#xff0c;在 26 个不同的国家/地区工作。 挑战 提高运营效率 原因&#xff1a;用户需要长途跋涉并完成多…

【外汇天眼】解析外汇交易平台:深度了解DD与NDD两大模式

外汇交易平台种类繁多&#xff0c;涵盖不同的分类与运营模式&#xff0c;令投资者难以甄别&#xff0c;也增加了选择的难度。为了解决这一问题&#xff0c;我们将更深入地了解外汇平台的多样性。 在线外汇交易平台主要分为两大类&#xff1a;处理平台模式&#xff08;Dealing …

JSON vs. CSV vs. YAML vs. XML vs. HDF5vs. XLS:数据格式之争

前言 数据处理是现代计算机科学和信息技术中至关重要的一部分。有效地选择和处理数据格式是数据科学、工程和各种应用中的关键环节。本文将深入探讨各种常见数据格式及其Python库的应用&#xff0c;旨在帮助读者更好地理解和应用这些数据格式&#xff0c;以及如何选择最适合自…

PC6404降压调整器负载大高集成低纹波800mA大电流输出

PC6406是一款由基准电压源、振荡电路、比较器、PWM/PFM 控制电路等构成的CMOS降压DC/DC调整器。利用PWM/PFM自动切换控制电路达到可调占空比&#xff0c;具有全输入电压范围&#xff08;1.8&#xff0d;5.5V&#xff09;内的低纹波、高效率和大输出电流等特点。PC6406内置功率M…

C++: 模板初阶

文章目录 一. 泛型编程二. 函数模板函数模板的原理函数模板的实例化隐式实例化: 让编译器根据实参推演模板参数的实际类型显示实例化: 在函数名后的<>中制定模板参数的世纪类型 模板参数的匹配原则 三. 类模板类模板的定义格式类模板的实例化 一. 泛型编程 如何实现一个…

Python练习

Python 练习一练习二练习三 练习一 实现代码&#xff1a; def merge(list1, list2):merged_list []i 0j 0while i < len(list1) and j < len(list2):if list1[i] < list2[j]:merged_list.append(list1[i])i 1else:merged_list.append(list2[j])j 1merged_list …