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.mzph.cn/bicheng/39883.shtml

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

相关文章

AI 会淘汰程序员吗?

前言 前些日子看过一篇文章&#xff0c;说国外一位拥有 19 年编码经验、会 100% 手写代码的程序员被企业解雇了&#xff0c;因为他的竞争对手&#xff0c;一位仅有 4 年经验、却善于使用 Copilot、GPT-4 的后辈&#xff0c;生产力比他更高&#xff0c;成本比他更低&#xff0c…

【数据分享】《中国金融年鉴》1986-2020年PDF版

而今天要免费分享的数据就是1986-2020年间出版的《中国金融年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 《中国金融年鉴》自1986年起&#xff0c;逐年记录着中国金融领域的发展历程、政策变化和市场动态。这部年鉴不仅是金融专业…

Halcon 基于分水岭的目标分割

一 分水岭 1 分水岭介绍 传统的分水岭分割方法&#xff0c;是一种基于拓扑理论的数学形态学的分割方法&#xff0c;其基本思想是把图像看作是地质学上的拓扑地貌&#xff0c;图像中每一像素的灰度值表示该点的海拔高度&#xff0c;每一个局部极小值及其周边区域称为集水盆地&…

ROS学习笔记(18):建图与定位(2)

0.前言 上文提到现在的我们已经进入到了SLAM领域的学习&#xff0c;会涉及到大量专业知识&#xff0c;作为一个自学的大三&#xff08;好吧也快大四了&#xff09;萌新并不能保证每次文章的专业性和准确性&#xff0c;所以&#xff0c;本人推荐大家能自己去查阅一些相关书籍和…

牛!手机、TV双端聚合,免费可同步!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 有不少小伙伴闲时会选择观看游戏、户外、娱乐等各类的直播&#xff0c;而关注的主播可能驻留在不同直播平台&#xff0c;需要下载多个APP&#xff0c;且切换非常不方便。 所以今天给大…

自定义动态数据源+事务控制

1&#xff1a;首先yml配置两个数据库的链接 spring:application:name: xxxxmain:banner-mode: OFFdatasource: # 默认数据源 datamarkdruid: # 关闭数据库的 web 访问stat-view-servlet:enabled: falseweb-stat-filter:enabled: falsefilt…

Linux系统之玩转SafeLine防火墙应用

Linux系统之玩转SafeLine防火墙应用 一、SafeLine介绍1.1SafeLine简介1.2 SafeLine功能1.3 SafeLine 的工作原理二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、部署SafeLine4.1 安…

一篇文章搞懂弹性云服务器和轻量云服务器的区别

前言 在众多的云服务器类型中&#xff0c;弹性云服务器和轻量云服务器因其各自的特点和优势&#xff0c;受到了广大用户的青睐。那么&#xff0c;这两者之间到底有哪些区别呢&#xff1f;本文将为您详细解析。 弹性云服务器&#xff1a;灵活多变的计算资源池 弹性云服务器&…

谷粒商城-个人笔记(集群部署篇一)

前言 ​学习视频&#xff1a;​Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强​学习文档&#xff1a; 谷粒商城-个人笔记(基础篇一)谷粒商城-个人笔记(基础篇二)谷粒商城-个人笔记(基础篇三)谷粒商城-个人笔记(高级篇一)谷粒商城-个…

【LeetCode的使用方法】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🔮LeetCode的使用方法 🔮LeetCode 是一个在线编程平台,广泛…

《昇思25天学习打卡营第7天|函数式自动微分》

文章目录 今日所学&#xff1a;一、函数与计算图二、微分函数与梯度计算三、Stop Gradient四、Auxiliary data五、神经网络梯度计算总结 今日所学&#xff1a; 今天我学习了神经网络训练的核心原理&#xff0c;主要是反向传播算法。这个过程包括将模型预测值&#xff08;logit…

无法定位程序输入点Z9 qt assertPKcS0i于动态链接库F:\code\projects\06_algorithm\main.exe

解决方法&#xff1a; 这个报错&#xff0c;是因为程序在运行时没要找到所需的dll库&#xff0c;如果把这个程序方法中对应库的目录下执行&#xff0c;则可正常执行。即使将图中mingw_64\bin 环境变量上移到msvc2022_64\bin 之前也不可以。 最终的解决方法是在makefile中设置环…

Python基础小知识问答系列-可迭代型变量赋值

1. 问题&#xff1a; 怎样简洁的把列表中的元素赋值给单个变量&#xff1f; 当需要列表中指定几个值时&#xff0c;剩余的变量都收集在一起&#xff0c;该怎么进行变量赋值&#xff1f; 当只需要列表中指定某几个值&#xff0c;其他值都忽略时&#xff0c;该怎么…

使用Redis实现消息队列:List、Pub/Sub和Stream的实践

摘要 Redis是一个高性能的键值存储系统&#xff0c;它的多种数据结构使其成为实现消息队列的理想选择。本文将探讨如何使用Redis的List、Pub/Sub和Stream数据结构来实现一个高效的消息队列系统。 1. 消息队列的基本概念 消息队列是一种应用程序之间进行通信的机制&#xff0…

660错题

不能局部求导,局部洛必达

Swift 中强大的 Key Paths(键路径)机制趣谈(上)

概览 小伙伴们可能不知道&#xff1a;在 Swift 语言中隐藏着大量看似“其貌不扬”实则却让秃头码农们“高世骇俗”&#xff0c;堪称卧虎藏龙的各种秘技。 其中&#xff0c;有一枚“不起眼”的小家伙称之为键路径&#xff08;Key Paths&#xff09;。如若将其善加利用&#xff…

pjsip环境搭建、编译源码生成.lib库

使用平台&#xff1a; windows qt(5.15.2) vs(2019)x86 pjsip版本以及第三方库使用 pjsip 2.10 ffmpeg4.2.1 sdl2.0.12pjsip源码链接&#xff1a; https://github.com/pjsip/pjproject源码环境配置 首先创建两个文件夹&#xff0c;分别是include、lib其中include放置ff…

p2p、分布式,区块链笔记: 通过libp2p的Kademlia网络协议实现kv-store

Kademlia 网络协议 Kademlia 是一种分布式哈希表协议和算法&#xff0c;用于构建去中心化的对等网络&#xff0c;核心思想是通过分布式的网络结构来实现高效的数据查找和存储。在这个学习项目里&#xff0c;Kademlia 作为 libp2p 中的 NetworkBehaviour的组成。 以下这些函数或…

Android 输入系统 InputStage

整体流程如上所说&#xff0c;简要归纳如下&#xff1a; 输入法之前的处理 输入法处理 输入法之后处理 综合处理 InputStage将输入事件的处理分成若干个阶段&#xff08;Stage&#xff09;, 如果当前有输入法窗口&#xff0c;则事件处理从 NativePreIme 开始&#xff0c;否…