vue组件深入介绍之插槽

了解插槽之前请先了解vue组件基础及注册

Vue2官网介绍
Vue3官网介绍

1、vue2插槽介绍

在2.6.0中,具名插槽和作用域插槽引入了一个新的统一语法(v-slot指令)。它将取代slot和slot-scope;

Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 < slot > 元素作为承载分发内容的出口。

允许父组件更改子组件模板内容,例如:

//父组件
<navigation-link url="/profile">Your Profile
</navigation-link>
//子组件NavigationLink.vue
<a v-bind:href="url" class="nav-link"><slot></slot>
</a>
//渲染结果
<a href="/profile" class="nav-link">Your Profile
</a>

如果 < navigation-link > 的 template 中没有包含一个 < slot > 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。

/*子组件*/
<template>
<a v-bind:href="url" class="nav-link"></a>
</template>
/*父组件*/
<navigation-link url="/profile"><span> Your Profile</span>a标签
</navigation-link>
//渲染结果,a标签中间无任何内容被渲染,span以及文本均被抛弃
<a href="/profile" class="nav-link">
</a>

2、vue3插槽介绍

//子组件
<script setup>
</script><template><button><slot></slot></button>
</template>
//父组件
<script setup>
import {ref} from 'vue';
import MyButton from '@/components/MyButton.vue'
</script><template><div class="index-main"><MyButton>点击<span style="display: inline-block; width:10px; height: 10px; border-radius: 50%; background-color: #f00; margin-left: 5px;"></span></MyButton>--></div>
</template>
/*渲染结果*/
<button>点击<sapn data-v-b4e148ca="" style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: rgb(255, 0, 0); margin-left: 5px;"></sapn></button>

插槽内容可以是任意合法的模板内容,不局限于文本;可以传入多个元素,甚至是组件

3、插槽渲染作用域

vue2和vue3插槽作用域须知如下:
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

/*父组件,父组件中的msg属性在父组件和子组件中均可渲染,但在MyButton子组件中无法获取msg的值,只有使用props传值后才可获取到*/
<script setup>
import {ref} from 'vue';
import MyButton from '@/components/MyButton.vue'const msg = ref('提交');
</script><template><div class="index-main"><div>{{msg}}</div><MyButton>{{msg}}</MyButton></div>
</template>

4、插槽的默认值设置

4.1、Vue2参考插槽——后备内容

/*vue2子组件设置默认值*/
<template>
<a v-bind:href="url" class="nav-link"><slot>跳转链接</slot>
</a>
</template>

4.2、Vue3参考插槽——默认内容

/*vue3子组件设置默认值*/
<script setup>
</script><template><button><slot>提交</slot></button>
</template>
/*vue3 父组件*/
<template><div class="index-main"><!-- 按钮文本为 提交 --><MyButton></MyButton><!-- 按钮文本为 立即提交 --><MyButton>立即提交</MyButton></div>
<template>

5、具名插槽

简单来说,当子组件有多个插槽时,为每个插槽设置不同名字,父组件中引用时可根据名字修改不同的插槽内容;

5.1、vue2具名插槽介绍

自 2.6.0 起有所更新。已废弃的使用 slot attribute;已废弃slot属性的用法具体请查看官网;

子组件插槽新语法:< slot>元素,此元素用油一个特殊的属性name,用name来定义额外的插槽;

一个不带 name 的 出口会带有隐含的名字“default”。

/*base-layout子组件*/
<div class="container"><header><slot name="header"></slot></header><main><slot></slot></main><footer><slot name="footer"></slot></footer>
</div>

父组件使用时:
可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

注意 v-slot 只能添加在 上;只有一种特殊情况,可暂不了解;

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:

/*父组件*/
<base-layout><template v-slot:header><h1>Here might be a page title</h1></template><p>A paragraph for the main content.</p><p>And another one.</p><!-- 更明确的写法<template v-slot:default><p>A paragraph for the main content.</p><p>And another one.</p></template>--><template v-slot:footer><p>Here's some contact info</p></template>
</base-layout>

新语法与vue3相同,具体示例不再冗余展示;具体示例请参照vue3;将对应的props传值修改为vue2写法即可;

5.2、Vue3具名插槽介绍

子组件包含多个插槽时:
< slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID;
这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 出口会隐式地命名为“default”

父组件的使用介绍:
要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 < template> 元素,并将目标插槽的名字传给该指令;
v-slot 有对应的简写 #,因此 < template v-slot:left> 可以简写为 <template #left>

示例参考

/*vue3 定义一个列表组件ListChild.vue,左侧图标,右侧箭头*/
<template><div class="list-bar" title="标题"><div v-if="leftShow" class="list-left"><slot name="left"><div class="list-leftIcon"></div></slot></div><div class="list-middle"><slot>列表内容</slot></div><div v-if="rightShow" class="list-rightIcon"><slot name="right">&gt;</slot></div></div>
</template><script setup>
const props = defineProps({leftShow:{type: Boolean,default: true},rightShow:{type: Boolean,default: true}
});
</script><style scoped>.list-bar{display: flex;display: -webkit-flex;align-items: center;-webkit-align-items: center;}.list-left{margin-right: 8px;}.list-leftIcon{width: 4px;height: 4px;background: #f00;}.list-rightIcon{margin-left: 10px;}
</style>
/*父组件*/
<script setup>
import ListChild from '@/components/ListChild.vue'
</script><template><div class="index-main"><!-- 使用默认效果 --><ListChild></ListChild><!-- 修改右侧内容 --><ListChild><template v-slot:right><!-- v-sole冒号后面为插槽的name --><!--  中间为重新定义的左侧内容  --><span style="color: #999; font-size: 12px;">2023-01-01</span></template></ListChild><!-- 修改左侧及主体内容 --><ListChild><template #left><span style="color: #999; font-size: 12px;">2023-01-01</span></template><!-- 默认不带name的均为默认插槽内容,是否 --><!-- <div>主体内容修改</div> --><template #default>主体内容</template></ListChild></div>
</template>

展示效果如下:
在这里插入图片描述

5.3、具名插槽内容替换图解

在这里插入图片描述

6、Vue3条件插槽

当需要根据插槽是否存在来判断某些内容时,可以结合$slots 属性与 v-if 来实现。(vue3独有特点)

在下面的示例中,我们定义了一个卡片组件,它拥有三个条件插槽:header、footer 和 default。 当 header、footer 或 default 存在时,我们希望包装它们以提供额外的样式:

<template><div class="card"><div v-if="$slots.header" class="card-header"><slot name="header" /></div><div v-if="$slots.default" class="card-content"><slot /></div><div v-if="$slots.footer" class="card-footer"><slot name="footer" /></div></div>
</template>

7、作用域插槽

备注:自 2.6.0 起有所更新。Vue2已废弃的使用 slot-scope;vue2和vue3的语法一致;但下面的示例为VUE3的组合式写法;

在插槽的渲染作用域中我们提到,插槽的内容无法访问到子组件的状态;

但是某些场景下可能需要父组件域内和子组件域内均能访问到此数据;此时我们需要让子组件渲染时将部分数据提供给插槽,以便父组件可以获取到;

7.1、默认插槽作用域插槽的设置

实现方法:将子组件的插槽设置一个属性;
如下面ListChild.vue子组件中slot标签上的count和list属性;也可直接使用v-bind绑定对象

父组件中写法:
v-slot=“slotProps”
v-slot:default=“slotProps”
缩写:
#default=“slotProps”
解构插槽:
v-slot=“{子组件属性名}”

/*子组件ListChild.vue*/
<template><div class="list-bar"><slot :count="1" :list="listVal" v-bind="{a:1,b:2}">列表内容</slot></div>
</template>
<script setup>import { ref } from 'vue';const listVal = ref('列表主题内容');
</script>
/*父组件index.vue*/
<script setup>import { ref } from 'vue';
</script>
<template><div class="index-main"><!-- slotProps可自定义名称slotProps的值为子组件slot标签上的所有自定义属性的对象合集{ "count": 1, "list": "列表", "a": 1, "b": 2 }--><ListChild v-slot="slotProps">{{slotProps.count}}--{{slotProps.list}}--{{slotProps.a}}--{{slotProps.b}}</ListChild><!-- 使用解构赋值 --><ListChild v-slot="{count,list,a,b}">{{count}}--{{list}}--{{a}}--{{b}}</ListChild><!-- 使用解构赋值,属性名重命名 --><ListChild v-slot="{count:countCopy ,list}">{{countCopy }}--{{list}}</ListChild></div>
</template>

7.2、具名作用域插槽

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

父组件中写法:
v-slot:name=“slotProps”
缩写:
#name=“slotProps”

注意插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽。因此最终 slotProps 的结果是 { “count”: 1, “list”: “列表主题内容” }

/*子组件ListChild.vue*/
<template><div class="list-bar"><slot name="label" :count="1" :list="listVal">列表内容</slot></div>
</template>
<script setup>import { ref } from 'vue';const listVal = ref('列表主题内容');
</script>
/*父组件index.vue*/
<ListChild v-slot:label="slotProps">{{slotProps}}
</ListChild>

注意要点:

  1. 当只有一个默认插槽时,可以把v-slot直接用在组件上;
  2. 默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:
  3. 只要出现多个插槽,请始终为所有的插槽使用完整的基于 的语法;

8、动态插槽名

动态指令参数在 v-slot 上也是有效的;也可简写;具体使用方法如下

/*子组件*/
<template><div class="list-bar" title="标题"><div v-if="leftShow" class="list-left"><slot name="left"><div class="list-leftIcon"></div></slot></div><div class="list-middle"><slot>列表内容</slot></div><div v-if="rightShow" class="list-rightIcon"><slot name="right">&gt;</slot></div></div>
</template>
/*父组件index.vue*/
<script setup>
import {ref} from 'vue';
const dynamicSlotName = ref('left');
setTimeout(()=>{dynamicSlotName.value = 'right';
},1000)
</script>
<template><div><ListChild :listData="listData" prop="title"><template v-slot:[dynamicSlotName]>1111</template></ListChild></div>
</template>

vue2官方文档未提及缩写写法,建议采用v-slot的写法定义动态插槽名;
Vue3可使用如下缩写写法;

/*缩写写法*/
<template #[dynamicSlotName]>1111</template>

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

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

相关文章

奇瑞被曝强制加班,“896”成常态且没有加班费

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 7 月 2 日消息&#xff0c;一位认证为“奇瑞员工”的网友近期发帖引发热议&#xff0c;奇瑞汽车内部存在强制加班行为&#xff0c;每周加班时长需大于 20 小时并且没有加班费&#xff0c;仅补贴 10 元…

elementui中@click短时间内多次触发,@click重复点击,做不允许重复点击处理

click快速点击&#xff0c;发生多次触发 2.代码示例&#xff1a; //html<el-button :loading"submitLoading" type"primary" click"submitForm">确 定</el-button>data() {return {submitLoading:false,}}//方法/** 提交按钮 */sub…

昇思25天学习打卡营第6天|数据变换 Transforms

学习目标&#xff1a;熟练掌握数据变换操作 熟悉mindspore.dataset.transforms接口 实践掌握常用变换 昇思大模型平台学习心得记录&#xff1a; 一、关于mindspore.dataset.transforms 1.1 变换 mindspore.dataset.transforms.Compose将多个数据增强操作组合使用。 mindspo…

OBD诊断(ISO15031) 04服务

文章目录 功能简介ISO 9141-2、ISO 14230-4和SAE J1850的诊断服务定义1、清除/重置与排放相关的诊断信息请求消息定义2、请求与排放相关的DTC响应消息定义3、报文示例 ISO 15765-4的诊断服务定义1、请求与排放相关的DTC请求消息定义2、请求与排放相关的DTC响应消息定义3、否定响…

信息安全体系架构设计

对信息系统的安全需求是任何单一安全技术都无法解决的&#xff0c;要设计一个信息安全体系架构&#xff0c;应当选择合适的安全体系结构模型。信息系统安全设计重点考虑两个方面&#xff1b;其一是系统安全保障体系&#xff1b;其二是信息安全体系架构。 1.系统安全保障体系 安…

linux下Java11无jre文件夹的问题

项目升级需要更高级的Java版本&#xff0c;于是下载了jdk-11.0.22_linux-x64_bin.tar.gz&#xff0c;解压后jdk-11.0.22下没有jre&#xff0c;导致eclipse下“build path”无法加载jre。 Java11以上版本不在提供jre&#xff0c;Java11安装后&#xff0c;需要如下处理&#xff1…

可充电纽扣电池ML2032充电电路设计

如图&#xff0c;可充电纽扣电池ML2032充电电路设计。 图中二极管是为了防止电流倒灌&#xff0c; 电阻分压出3.66v&#xff0c;再减掉二极管压降&#xff08;约0.4v)得3.26V&#xff0c;加在电池正负极充电。 随着电池电量的积累&#xff0c;充电电流逐步减小&#xff0c;极限…

探索迁移学习:通过实例深入理解机器学习的强大方法

探索迁移学习&#xff1a;通过实例深入理解机器学习的强大方法 &#x1f341;1. 迁移学习的概念&#x1f341;2. 迁移学习的应用领域&#x1f341;2.1 计算机视觉&#x1f341;2.2 自然语言处理&#xff08;NLP&#xff09;&#x1f341;2.3 医学图像分析&#x1f341;2.4 语音…

新手教学系列——慎用Flask-SQLAlchemy慢日志记录

在使用 Flask-SQLAlchemy 开发应用时,了解和避免潜在的问题是非常重要的。特别是在常驻进程和循环执行任务的场景下,慢查询记录功能(SQLALCHEMYRECORDQUERIES)可能会引发严重的内存泄漏问题。本文将详细介绍这个问题,并提供解决方案,帮助你在开发过程中避免掉入这些陷阱。…

Java开源ERP系统Axelor汉化方法初探

Axelor简介 汉化过程介绍 定义语言和本地化 导出多语言记录 导入翻译 验证翻译 调整翻译 Axelor简介 2024年6月份Axelor ERP发布了8.1版本&#xff0c;适配JDK11及PostgreSQL12及以上版本&#xff08;7及以前版本适配JDK8及PostgreSQL10&#xff09;数据库。v8版本较之前…

Oracle - 数据库打补丁实践

原文&#xff1a;https://www.cnblogs.com/ddzj01/p/12097467.html 一、概述 本文将介绍如何给oracle数据库打最新补丁&#xff0c;数据库版本为11.2.0.4单实例&#xff0c;操作系统为redhat6.5 二、下载相关升级包 1. 登录MOS&#xff0c;查阅(ID 2118136.2)&#xff0c;下载…

TDD测试驱动开发

为什么需要TDD&#xff1f; 传统开发方式&#xff0c;带来大量的低质量代码&#xff0c;而代码质量带来的问题&#xff1a; 1.在缺陷的泥潭中挣扎 开发长时间投入在缺陷的修复中&#xff0c;修复完依赖测试做长时间的回归测试 2.维护困难&#xff0c;开发缓慢 比如重复代码&am…

Stm32的DMA的学习

一&#xff0c;介绍 二&#xff0c;DMA框图 三&#xff0c;DMA通道 四&#xff0c;相关HAL库函数 五&#xff0c;配置DMA 六&#xff0c;Stm32CubeMX配置 【13.1】减少CPU传输负载 DMA直接存储器访问—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili

sideloadly 苹果自签和sidestore手机续签ipa记录

sideloadly 地址&#xff1a;https://sideloadly.io/#download 直接安装对应系统软件&#xff0c;然后吧ipa 拖到里面续签&#xff0c;缺点每7天需要电脑续签 如果续签保留数据需要对应的位置开启 enable file sharing 勾选 和 bundle id 修改 注意的地方需要电脑和手机appi…

echarts-wordcloud:打造个性化词云库

前言 在当今信息爆炸的时代&#xff0c;如何从海量的文本数据中提取有用的信息成为了一项重要的任务。词云作为一种直观、易于理解的数据可视化方式&#xff0c;被广泛应用于文本分析和可视化领域。本文将介绍一种基于 echarts-wordcloud 实现的词云库&#xff0c;通过其丰富的…

06-java基础——集合的复习

集合的体系结构 集合主要分为两类&#xff1a; 单列集合双列集合 一、单列集合 list系列集合&#xff1a;添加的元素是有序、可重复、有索引的。 有序&#xff1a;指的是存和取的顺序是一致的 set系列集合&#xff1a;添加的元素是无序、不可重复、无索引的。 collection&…

Python爬虫实战案例——王者荣耀皮肤抓取

大家好&#xff0c;我是你们的老朋友——南枫&#xff0c;今天我们一起来学习一下该如何抓取大家经常玩的游戏——王者荣耀里面的所有英雄的皮肤。 老规矩&#xff0c;直接上代码&#xff1a; 导入我们需要使用到的&#xff0c;也是唯一用到的库&#xff1a; 我们要抓取皮肤其…

统计信号处理基础 习题解答11-11

题目 考虑矢量MAP估计量 证明这个估计量对于代价函数 使贝叶斯风险最小。其中&#xff1a;, &#xff0c;且. 解答 贝叶斯风险函数&#xff1a; 基于概率密度的非负特性&#xff0c;上述对积分要求最小&#xff0c;那就需要内层积分达到最小。令内层积分为&#xff1a; 上述积…

【SkiaSharp绘图12】SKCanvas方法详解(一)清空、裁切区域设置、连接矩阵、注释、弧与扇形、图集、九宫格绘图、圆

文章目录 SKCanvas 方法Clear 清空ClipPath/ClipRect/ClipRegion/ClipRoundRect 设置裁切区域Concat 连接矩阵DrawAnnotation绘制注释DrawArc绘制椭圆弧、扇形DrawAtlas绘制图集(一个图像、多个区域、多个缩放、一次绘制&#xff09;DrawBitmap绘制图像DrawBitmapNinePatch九宫…

停车场车牌识别计费系统,用Python如何实现?

关注星标&#xff0c;每天学习Python新技能 前段时间练习过的一个小项目&#xff0c;今天再看看&#xff0c;记录一下~ 项目结构 说明&#xff1a; datefile文件夹&#xff1a;保存车辆信息表的xlsx文件 file文件夹&#xff1a;保存图片文件夹。ic_launcher.jpg是窗体的右上角…