Vue之插槽(slot)
插槽是vue中的一个非常强大且灵活的功能,在写组件时,可以为组件的使用者预留一些可以自定义内容的占位符。通过插槽,可以极大提高组件的客服用和灵活性。
插槽大体可以分为三类:默认插槽,具名插槽和作用域插槽。
下面将一一介绍。
①默认插槽
这种插槽没有指定名称,用于接受父组件传递的未明确指定插槽名称的内容。在子组件中使用<slot></slot>定义插槽所在位置,父组件在书写子组件的标签体里书写插入到该插槽的内容。
代码如下:
父组件:index.vue
<!--* @Author: RealRoad* @Date: 2024-10-18 10:49:28* @LastEditors: Do not edit* @LastEditTime: 2024-11-14 14:13:02* @Description: * @FilePath: \project_10_08\vite-project\src\views\home\index.vue
--><template><div class="box"><Category class="content"><div>我是文本</div><img src="https://img0.baidu.com/it/u=454995986,3330485591&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=375" alt=""></Category><Category class="content"><el-button type="primary" size="default" @click="">一个按钮</el-button></Category><Category class="content"><el-card shadow="always" :body-style="{ padding: '20px' }"><div slot="header"><span>卡片标题</span></div><!-- card body --><div>卡片体</div></el-card></Category></div>
</template><script setup lang="ts">
import {ref,reactive} from 'vue'
import Category from './Category.vue'
</script><style scoped lang="scss">
.box{display:flex;justify-content: space-evenly;margin-top: 20px;.content{margin-left: 10px;background:pink;text-align: center;width: 400px;height: 600px;img{width: 100%;}}
}
</style>
子组件:Category.vue
<template><div>我是子组件<!-- 一个默认插槽 --><slot>插槽的默认内容</slot></div>
</template><script setup lang="ts">
import {ref,reactive} from 'vue'</script><style scoped></style>
来看效果:
当然了,在子组件中,可以书写插槽的默认内容,就是说如果父组件没有书写任何内容,就会默认使用子组件插槽内的内容。
再写一个子组件,看一下效果
②具名插槽
顾名思义,就是带有名称的插槽,用于接受父组件中明确指定插槽名称的内容。
这里需要注意,vue2和vue3的写法略有不同,因为v3兼容v2,所有有些老版本的项目写的插槽还是v2的写法。
首先看v3的具名插槽写法:
子组件的写法相同,在子组件中使用<slot name="插槽名"></slot>就可以给插槽起一个名字。
子组件(NamedSlot.vue):
<template><div>我是子组件2<!-- 一个默认插槽 --><slot name="top">插槽的默认内容</slot><slot name="bottom">插槽的默认内容</slot></div>
</template><script setup lang="ts">
import {ref,reactive} from 'vue'</script><style scoped></style>
来到父组件(index.vue):v3
<!--* @Author: RealRoad* @Date: 2024-10-18 10:49:28* @LastEditors: Do not edit* @LastEditTime: 2024-11-14 14:40:49* @FilePath: \project_10_08\vite-project\src\views\home\index.vue* @Description:
--><template><div class="box"><NamedSlot class="content"><template #top><div >我是文本</div></template><template #bottom><img src="https://img0.baidu.com/it/u=454995986,3330485591&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=375" alt=""></template></NamedSlot><Category class="content"><el-button type="primary" size="default" @click="">一个按钮</el-button></Category><Category class="content"><el-card shadow="always" :body-style="{ padding: '20px' }"><div slot="header"><span>卡片标题</span></div><!-- card body --><div>卡片体</div></el-card></Category><Category class="content"></Category></div>
</template><script setup lang="ts">
import {ref,reactive} from 'vue'
import Category from './Category.vue'
import NamedSlot from './NamedSlot.vue';
</script><style scoped lang="scss">
.box{display:flex;justify-content: space-evenly;margin-top: 20px;.content{margin-left: 10px;background:pink;text-align: center;width: 400px;height: 600px;img{width: 100%;}}
}
</style>
可以对比一下上面的默认插槽,我们只修改了第一个子组件,其他的还是保持不变。
先看一下效果:
效果是一样的,不过是我们在子组件中起了名字,这样我们就可以在父组件随便改变顺序,就不用改变代码顺序了,直接修改插槽的名字即可。
说一下v3中的父组件的具名插槽的写法:
<子组件名称 >
<template #插槽名>
插槽内容
</template>
</子组件名称>
这样的格式,借用了template标签,并在标签上使用#的简写形式,也是现在element-plus等新版UI组件库使用的方式。
说完了v3,那一定要说一下老版本的v2写法,毕竟老项目中的都是这样的写法:
<子组件名称>
<子组件内容--标签 slot="插槽名"> </子组件内容--标签 >
</子组件名称>
注意:这里面在测试的时候出现了一个误区,我直接卸载了子组件名称的属性上,导致里面的内容也是无法正常显示。
这就比较难受,在vue3项目中使用vue2的老具名插槽用法不显示,原因可能有很多,保险起见,还是专门用脚手架建立的vue2项目中进行测试。
所以紧急来到上次做的vue2项目中,进行老语法测试:
父组件:index.vue
<!--* @Author: RealRoad* @Date: 2024-11-12 09:25:23* @LastEditors: Do not edit* @LastEditTime: 2024-11-14 15:29:28* @Description: * @FilePath: \datalized-crm-ui\datalized-crm-ui\src\views\test\index.vue
-->
<!--* @Author: RealRoad* @Date: 2024-11-12 09:25:23* @LastEditors: Do not edit* @LastEditTime: 2024-11-12 16:10:43* @Description: * @FilePath: \datalized-crm-ui\datalized-crm-ui\src\views\test\index.vue
-->
<template><div><ComponentA ><div slot="top">测试一波具名插槽<img src="https://img1.baidu.com/it/u=1047145501,4073770646&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1731690000&t=14c402c69d53274bb7fa9af0d0e0e392" alt=""></div></ComponentA><ComponentB /><!-- <a-form layout="inline" class="my-customer-form" @keyup.enter.native="searchQuery"><a-form-item label="商机名称"><a-inputplaceholder="请输入商机名称"></a-input></a-form-item><a-form-item label="客户名称"><a-inputplaceholder="请输入客户名称"allowClear></a-input></a-form-item><a-form-item label="赢单率"><a-select:getPopupContainer="node => node.parentNode"placeholder="请选择赢单率"default-value="10%"style="width: 100%":style="{ width: searchItemWidth }"><a-select-option value="10%"> 10%</a-select-option><a-select-option value="20%"> 20%</a-select-option><a-select-option value="30%"> 30%</a-select-option><a-select-option value="40%"> 40%</a-select-option><a-select-option value="50%"> 50%</a-select-option><a-select-option value="60%"> 60%</a-select-option><a-select-option value="70%"> 70%</a-select-option><a-select-option value="80%"> 80%</a-select-option><a-select-option value="90%"> 90%</a-select-option><a-select-option value="100%"> 100%</a-select-option></a-select></a-form-item><a-form-item label="商机状态"><j-dict-select-tagtype="radioButton"dictCode="chance_status"/></a-form-item></a-form><hr>展示一下过度<div><a-button type="primary" @click="isShow=!isShow">显示/隐藏</a-button><transition name="mez" appear @afterEnter="handleEnter"@after-leave="handleLeave"@appear="handleAppear"@after-appear="myhandleEnter"@before-enter="myEnter"@enter="handleEnter"@leave="handleLeave"><h1 v-show="isShow" >测试文本</h1></transition></div>1112 --></div>
</template><script>import ComponentA from './brotherA.vue'
import ComponentB from './brotherB.vue'
import JDictSelectTag from '@/components/dict/JDictSelectTag'
export default {name: 'Test',data() {return {searchItemWidth:'200px',isShow:true};},methods: {handleEnter(){console.log('after-enter');},handleLeave(){console.log('after-leave');},handleAppear(){console.log('appear');},handleEnter(){console.log('enter');},handleLeave(){console.log('leave');},myEnter(){console.log('before-enter');},myhandleEnter(){console.log('after-appear');},},components: {ComponentA,ComponentB},}
</script><style lang="less" scoped>
// @import '~@assets/less/common.less';h1{background-color: rgb(98, 57, 133);}
//进入的起点
.mez-enter,.mez-leave-to{transform: translateX(-100%);
}
//进入的过程
.mez-enter-active,.mez-leave-active{// animation: identifier 1s linear;transition: 0.5s linear;
}
// .mez-leave-active{
// // animation: identifier 1s linear reverse;
// }
//进入的终点
.mez-enter-to,.mez-leave{transform: translateX(0);
}
//离开的起点
// .mez-leave{
// transform: translateX(0);
// }
// //离开的终点
// .mez-leave-to{
// transform: translateX(-100%);
// }// @keyframes identifier {
// from{
// transform: translateX(-100%);
// }
// to{
// transform: translateX(0px);
// }
// }
</style>
子组件brotherA.vue:
template>
<div>兄弟A组件<!-- <a-button type="primary" size="default" @click="handleClick">点我给B兄弟传值</a-button> --><slot name="top">如果父组件没有内容显示我</slot>
</div>
</template><script>
export default {name: '',data() {return {};},methods: {// handleClick() {// this.$emit('sendValue', '兄弟A组件传给B的参数');// }}
}
</script><style scoped></style>
来看效果:
果然和脚手架有关,可以正常使用。在vue3项目中哪怕是写成了不是setup语法糖的写法,也是不能正常显示,这里兄弟们需要注意一下,也有可能是我用vite建立的是vue3的项目,因为既有vue3的setup语法糖写法,又有vue2的export default{}写法,造成的冲突。【另外,这里还有一个vue2.7还是啥来着提出的配合template的<template v-slot:插槽名></template>的简写写法,这个就不展开说了,知道就行。】
③作用域插槽
它是一种特殊的插槽,允许子组件爱你将数据暴露给父组件的插槽内容。在子组件中,语法为<slot :数据名=“数据值”></slot>的写法将自己的数据传递给插槽。
而在父组件中,通过<template v-slot:插槽名称=“slotProps”>接受数据,并使用slotProps来访问传递过来的数据。
子组件:
<template><div><slot :users="userList"></slot></div>
</template><script setup>
import { reactive } from 'vue';// 定义一个响应式数组,作为作用域插槽的数据源
const userList = reactive([{ name: 'Alice', age: 25 },{ name: 'Bob', age: 30 },{ name: 'Charlie', age: 35 }
]);
</script><style scoped>
/* 子组件的样式(如果需要的话) */
</style>
父组件:
<template><div><h1>作用域插槽示例</h1><ChildComponent><!-- 使用 v-slot 接收作用域插槽的数据 --><template #default="{ users }"><ul><li v-for="user in users" :key="user.name">{{ user.name }} - {{ user.age }}</li></ul></template></ChildComponent></div>
</template><script setup>
import ChildComponent from './ChildComponent.vue';
</script><style scoped>
/* 父组件的样式(如果需要的话) */
</style>
相关文章:

Vue之插槽(slot)
插槽是vue中的一个非常强大且灵活的功能,在写组件时,可以为组件的使用者预留一些可以自定义内容的占位符。通过插槽,可以极大提高组件的客服用和灵活性。 插槽大体可以分为三类:默认插槽,具名插槽和作用域插槽。 下面…...

分布式服务高可用实现:复制
分布式服务高可用实现:复制 1. 为什么需要复制 我们可以考虑如下问题: 当数据量、读取或写入负载已经超过了当前服务器的处理能力,如何实现负载均衡?希望在单台服务器出现故障时仍能继续工作,这该如何实现ÿ…...

基于yolov8、yolov5的车型检测识别系统(含UI界面、训练好的模型、Python代码、数据集)
摘要:车型识别在交通管理、智能监控和车辆管理中起着至关重要的作用,不仅能帮助相关部门快速识别车辆类型,还为自动化交通监控提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的车型识别模型,该模型使用了…...

机器学习—决定下一步做什么
现在已经看到了很多不同的学习算法,包括线性回归、逻辑回归甚至深度学习或神经网络。 关于如何构建机器学习系统的一些建议 假设你已经实现了正则化线性回归来预测房价,所以你有通常的学习算法的成本函数平方误差加上这个正则化项,但是如果…...
Java Optional详解:避免空指针异常的优雅方式
在 Java 编程中,空指针异常(NullPointerException)一直是困扰开发者的常见问题之一。为了更安全、优雅地处理可能为空的值,Java 8 引入了 Optional 类。Optional 提供了一种函数式的方式来表示一个值可能存在或不存在,…...
SpringBoot开发——整合EasyExcel实现百万级数据导入导出功能
文章目录 一、EasyExcel 框架及特性介绍二、实现步骤1、项目创建及依赖配置(pom.xml)2、项目文件结构3、配置文件(application.yml)4、启动类 Application.java5、配置类 EasyExcelConfig.java6、服务接口定义及实现 ExcelService.java7、控制器类 ExcelController.java8、…...
AcWing 1097 池塘计数 flood fill bfs搜索
代码 #include <bits/stdc.h> using namespace std;const int N 1010, M N * N;typedef pair<int, int> PII;int n, m;char g[N][N]; bool st[N][N]; PII q[M];void bfs (int xx, int yy) {int hh 0, tt -1;q[ tt] {xx, yy};st[xx][yy] true;while (hh <…...

R门 - rust第一课陈天 -内存知识学习笔记
内存 #mermaid-svg-1NFTUW33mcI2cBGB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-1NFTUW33mcI2cBGB .error-icon{fill:#552222;}#mermaid-svg-1NFTUW33mcI2cBGB .error-text{fill:#552222;stroke:#552222;}#merm…...

java itext后端生成pdf导出
public CustomApiResult<String> exportPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {// 防止日志记录获取session异常request.getSession();// 设置编码格式response.setContentType("application/pdf;charsetUTF-8")…...

信号-3-信号处理
main 信号捕捉的操作 sigaction struct sigaction OS不允许信号处理方法进行嵌套:某一个信号正在被处理时,OS会自动block改信号,之后会自动恢复 同理,sigaction.sa_mask 为捕捉指定信号后临时屏蔽的表 pending什么时候清零&…...
38配置管理工具(如Ansible、Puppet、Chef)
每天五分钟学Linux | 第三十八课:配置管理工具(如Ansible、Puppet、Chef) 大家好!欢迎再次来到我们的“每天五分钟学Linux”系列教程。在前面的课程中,我们学习了如何安装和配置邮件服务器。今天,我们将探…...
网络技术-定义配置ACL规则的语法和命令
定义ACL(访问控制列表)规则时,具体命令会根据所使用的设备和操作系统而有所不同。以下是一些常见的设备和操作系统中定义ACL规则的命令示例: 一:思科(Cisco)路由器/交换机 在思科设备中&#…...

动态规划一>子数组系列
题目: 2.解析: 代码: public int maxSubArray(int[] nums) {int n nums.length;int[] dp new int[n 1];int ret Integer.MIN_VALUE;for(int i 1; i < n; i){dp[i] Math.max(nums[i - 1], dp[i - 1] nums[i - 1]);ret Math.max(…...

一觉睡醒,全世界计算机水平下降100倍,而我却精通C语言——scanf函数
大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Fei Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。* 这一节我们主要来学习scanf的基本用法,了解scanf返回值,懂得scanf占位符和…...

Altium Designer使用技巧(五)
一、敷铜(快捷键T-G-A) 1、工具栏点“设计”—>“规则”。 可以修改覆铜连线的宽度,也可以选择“直接连接”使得铜和网络节点完全相连。 这里方式有三种,可根据需要各个人习惯去设置。 2、敷铜与线全链接 (1)少量的话可右键“…...

Docker 的安装与使用
Docker 的安装 Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。 Docker CE 的安装请参考官方文档…...
Android Studio 中三方库依赖无法找到的解决方案
目录 错误信息解析 解决方案 1. 检查依赖版本 2. 检查 Maven 仓库配置 3. 强制刷新 Gradle 缓存 4. 检查网络连接 5. 手动下载依赖 总结 相关推荐 最近,我在编译一个 Android 老项目时遇到了一个问题,错误信息显示无法找到 com.gyf.immersionba…...
PGMP练-DAY24
DAY241A program has completed and closed. The training for the receiving organization has also delivered. But the stakeholders still concern that the benefits cannot be realized in long term.What does the program manager review to improve the situation?项…...

【C++动态规划 最长公共子序列】1035. 不相交的线|1805
本文涉及知识点 C动态规划 LeetCode1035. 不相交的线 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足: nums1[i] nums2[j] 且绘制的…...

FFmpeg的基本结构
FFmpeg框架可以简单分为两层,上层是以ffmpeg、ffplay、ffprobe为代表的命令行工具;其底层支撑是一些基础库,包含AVFormat、AVCodec、AVFilter、AVDevices、AVUtils等模块库。 常用函数如下: 1. AVFormat 封装/解封装模块 avf…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...