vue-插槽作用域实用场景
vue-插槽作用域实用场景
- 1.插槽
- 1.1 自定义列表渲染
- 1.2 数据表格组件
- 1.3 树形组件
- 1.4 表单验证组件
- 1.5 无限滚动组件
1.插槽
插槽感觉知道有这个东西,但是挺少用过的,每次看到基本都会再去看一遍用法和概念。但是在项目里,自己还是没有用到过。总结下一些可能用到的场景,下次直接这样写了。
1.1 自定义列表渲染
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import { reactive } from 'vue';
const myItems = reactive([{name: 'A',age: 18},{name: 'B',age: 19},{name: 'C',age: 20}
]
)
</script>
<template><HelloWorld :items="myItems"><template v-slot:default="slotProps"><span>{{ slotProps.item.name }}</span><button @click="doSomething(slotProps.item)">操作</button></template></HelloWorld>
</template><script setup>
import { defineProps } from 'vue';defineProps({items: {type: Array,default: () => []}
})
</script>
<template><ul><li v-for="item in items" :key="item.id"><slot :item="item"></slot></li></ul>
</template>
效果:

拓展性很强。
1.2 数据表格组件
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import { reactive } from 'vue';
const tableData = reactive([{name: 'A',age: 18},{name: 'B',age: 19},{name: 'C',age: 20}]
)const columns = reactive([{label: '姓名',key: 'name'},{label: '年龄',key: 'age'},{label: '性别',key: 'sex'},{ key: 'actions', label: '操作' }]
)
</script>
<template><HelloWorld :columns="columns" :data="tableData"><template v-slot:actions="{ row }"><button @click="edit(row)">编辑</button><button @click="del(row)">删除</button></template></HelloWorld>
</template><template><table><thead><tr><th v-for="column in columns" :key="column.key">{{ column.label }}</th></tr></thead><tbody><tr v-for="row in data" :key="row.id"><td v-for="column in columns" :key="column.key"><slot :name="column.key" :row="row">{{ row[column.key] }}</slot></td></tr></tbody></table>
</template><script setup>
import { defineProps } from 'vue';
defineProps({columns: Array,data: Array,
});
</script>
效果:

1.3 树形组件
<template><div class="tree-node"><slot :node="node" :toggle="toggle" :expandTree="expandTree" name="trangle"><span v-if="node.children.length > 0" @click="toggle">{{ expanded ? '▼' : '▶' }}</span></slot><slot :node="node" :toggle="toggle" :expandTree="expandTree"><div>{{ node.label }}</div></slot><div v-if="expanded" class="tree-node-children"><HelloWorld v-for="child in node.children" :key="child.id" :node="child"><template v-slot="childSlotProps"><slot v-bind="childSlotProps"></slot></template></HelloWorld></div></div>
</template>
<script setup>
import HelloWorld from './HelloWorld.vue'
import { defineProps, ref } from 'vue';
const props = defineProps({node: {type: Object,required: true}
})
const expanded = ref(false)
const toggle = () => {console.log(999)expanded.value = !expanded.value
}
const expandTree = () => {expanded.value = true
}
</script>
<style>
.tree-node {position: relative;cursor: pointer;
}.tree-node-children {position: relative;padding-left: 20px;/* 这个值决定了每一层的缩进量 */
}.tree-node>span {margin-left: 0;
}
</style><script setup>
import HelloWorld from './components/HelloWorld.vue'
import { reactive } from 'vue';const rootNode = reactive({id: 1,label: '根节点',children: [{id: 2, label: '子节点1', children: [{ id: 3, label: '子节点1-1', children: [] }]},{ id: 4, label: '子节点2', children: [] }]
})const addChild = (node, expandTree) => {const newId = Date.now()expandTree()node.children.push({id: newId,label: `新子节点${newId}`,children: []})
}
</script>
<template><HelloWorld :node="rootNode"><template v-slot="{ node, toggle, expandTree }"><span @click="toggle">{{ node.label }}</span><button @click="addChild(node, expandTree)">添加子节点</button></template></HelloWorld>
</template>
效果:

1.4 表单验证组件
<script setup>
import { ref, watch, defineProps, defineEmits } from 'vue'const props = defineProps({rules: {type: Array,default: () => []},modelValue: {type: String,default: ''}
})const emit = defineEmits(['update:modelValue'])const value = ref(props.modelValue)
const error = ref('')const validate = () => {for (const rule of props.rules) {if (!rule.validate(value.value)) {error.value = rule.messagereturn false}}error.value = ''return true
}watch(() => props.modelValue, (newValue) => {value.value = newValue
})watch(value, (newValue) => {emit('update:modelValue', newValue)
})
</script><template><div class="a"><slot :value="value" :error="error" :validate="validate"></slot><span v-if="error">{{ error }}</span></div>
</template>
<style lang="scss" scoped>
.a{position: relative;span{color: red;position: absolute;left: 0;bottom: -24px;font-size: 14px;}
}</style>//使用
<script setup>
import FormField from './components/HelloWorld.vue'
import { ref } from 'vue';const email = ref('')const emailRules = [{validate: (value) => /.+@.+\..+/.test(value),message: '请输入有效的电子邮件地址'}
]
</script>
<template><FormField :rules="emailRules" v-model="email"><template v-slot="{ value, error, validate }">邮箱<input :value="value" @input="$event => { email = $event.target.value; validate(); }":class="{ 'is-invalid': error }" /></template></FormField>
</template><style >
input{outline: none;
}
.is-invalid:focus {border-color: red;
}
</style>
效果:

1.5 无限滚动组件
<script setup>
import { ref, onMounted, defineProps } from 'vue'const props = defineProps({fetchItems: {type: Function,required: true}
})const visibleItems = ref([])
const loading = ref(false)const handleScroll = async (event) => {const { scrollTop, scrollHeight, clientHeight } = event.targetif (scrollTop + clientHeight >= scrollHeight - 20 && !loading.value) {loading.value = trueconst newItems = await props.fetchItems()visibleItems.value = [...visibleItems.value, ...newItems]loading.value = false}
}onMounted(async () => {visibleItems.value = await props.fetchItems()
})
</script><template><div @scroll="handleScroll" style="height: 200px; overflow-y: auto;"><slot :items="visibleItems"></slot><div v-if="loading">加载中...</div></div>
</template>//使用
<script setup>
import InfiniteScroll from './components/HelloWorld.vue'
import { ref } from 'vue';let page = 0
const fetchMoreItems = async () => {// 模拟API调用await new Promise(resolve => setTimeout(resolve, 1000))page++return Array.from({ length: 10 }, (_, i) => ({id: page * 10 + i,content: `Item ${page * 10 + i}`}))
}
</script>
<template><InfiniteScroll :fetch-items="fetchMoreItems"><template #default="{ items }"><div v-for="item in items" :key="item.id">{{ item.content }}</div></template></InfiniteScroll>
</template>相关文章:
vue-插槽作用域实用场景
vue-插槽作用域实用场景 1.插槽1.1 自定义列表渲染1.2 数据表格组件1.3 树形组件1.4 表单验证组件1.5 无限滚动组件 1.插槽 插槽感觉知道有这个东西,但是挺少用过的,每次看到基本都会再去看一遍用法和概念。但是在项目里,自己还是没有用到过…...
Prometheus+Grafana 监控 K8S Ingress-Ningx Controller
文章目录 一、prometheus中添加ingress-nginx的服务发现配置二、ingress-nginx controller的service添加端口暴露监控指标三、grafana添加ingress-nginx controller的监控模版 ingress-nginx默认是没有开启监控指标的,需要我们在ingress-nginx controller的svc里面开…...
如何在Visual Studio 2019中创建.Net Core WPF工程
如何在Visual Studio 2019中创建.Net Core WPF工程 打开Visual Studio 2019,选择Create a new project 选择WPF App(.Net Core) 输入项目名称和位置,单击Create 这样我们就创建好了一个WPF工程 工程文件说明 Dependencies 当前项目所使用的依赖库&…...
自然语言处理(NLP)论文数量的十年趋势:2014-2024
引言 近年来,自然语言处理(NLP)已成为人工智能(AI)和数据科学领域中的关键技术之一。随着数据规模的不断扩大和计算能力的提升,NLP技术从学术研究走向了广泛的实际应用。通过观察过去十年(2014…...
.net core API中使用LiteDB
LiteDB介绍 LiteDB 是一个小巧、快速和轻量级的 .NET NoSQL 嵌入式数据库。 无服务器的 NoSQL 文档存储简单的 API,类似于 MongoDB100% 的 C# 代码支持 .NET 4.5 / NETStandard 1.3/2.0,以单个 DLL(不到 450KB)形式提供线程安全…...
YOLO_V8分割
YOLO_V8分割 YOLO安装 pip install ultralytics YOLO的数据集转化看csdn 数据标注EIseg EIseg这块,正常安装就好,但是numpy和各类包都容易有冲突,python版本装第一点 数据标注过程中,记得把JSON和COCO都点上,把自…...
根据请求错误的状态码判断代理配置问题
SafeLine,中文名 “雷池”,是一款简单好用, 效果突出的 Web 应用防火墙(WAF),可以保护 Web 服务不受黑客攻击。 雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 SQL 注入、XSS、 代码注入、命…...
Python 网络爬虫高阶用法
网络爬虫成为了自动化数据抓取的核心工具。Python 拥有强大的第三方库支持,在网络爬虫领域的应用尤为广泛。本文将深入探讨 Python 网络爬虫的高阶用法,包括处理反爬虫机制、动态网页抓取、分布式爬虫以及并发和异步爬虫等技术。以下内容结合最新技术发展…...
芯片Tapeout前GDS Review | Calibre中如何切出gds中指定区域版图?
在SoC芯片实现阶段我们会用到很多模拟IP,IO。对于这类模拟IP相关的电源连接,ESD保护电路连接,信号线连接都需要跟IP Vendor进行Review。但芯片整体版图涉及商业机密,我们不希望整个芯片的版图被各大vendor看到,因此我们…...
43 | 单例模式(下):如何设计实现一个集群环境下的分布式单例模式?
上两篇文章中,我们针对单例模式,讲解了单例的应用场景、几种常见的代码实现和存在的问题,并粗略给出了替换单例模式的方法,比如工厂模式、IOC 容器。今天,我们再进一步扩展延伸一下,一块讨论一下下面这几个…...
PHP如何解决异常处理
在PHP中,异常处理是通过使用try、catch、throw以及finally这几个关键字来实现的。以下是一个简单的介绍和示例: 异常处理的基本步骤 抛出异常: 使用throw关键字抛出一个异常对象。异常对象通常是Exception类或其子类的实例。 捕获异常&…...
C++ socket编程(3)
前面文章,介绍了一个简单socket通讯Demo, 客户端和服务器进行简单的交互。两个代码都很简单,如果情况一复杂,就会出错。这节我们把代码完善一下,实现一个客户端输入,发送,服务器echo的交互。本文…...
Collection-LinkedList源码解析
文章目录 概述LinkedList实现底层数据结构构造函数getFirst(), getLast()removeFirst(), removeLast(), remove(e), remove(index)add()addAll()clear()Positional Access 方法查找操作 概述 LinkedList同时实现了List接口和Deque接口,也就是说它既可以看作一个顺序…...
vue判断对象数组里是否有重复数据
TOCvue判断对象数组里是否有重复数据 try {//通过产品编码赛选出新的数组 在比较let names this.goodsJson.map(item > item["productCode"]);let nameSet new Set(names)if (nameSet.size ! names.length) {this.$message({message: 警告!产品选项…...
CSS 3D转换
在 CSS 中,除了可以对页面中的元素进行 2D 转换外,您也可以对象元素进行 3D转换(将页面看作是一个三维空间来对页面中的元素进行移动、旋转、缩放和倾斜等操作)。与 2D 转换相同,3D 转换同样不会影响周围的元素&#x…...
51单片机数码管循环显示0~f
原理图: #include <reg52.h>sbit dulaP2^6;//段选信号 sbit welaP2^7;//位选信号unsigned char num;//数码管显示的数字0~funsigned char code table[]{ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};//定义数码管显…...
【编程进阶知识】Java NIO:掌握高效的I/O多路复用技术
Java NIO:掌握高效的I/O多路复用技术 摘要: 本文将带你深入了解Java NIO(New I/O)中的Selector类,探索如何利用它实现高效的I/O多路复用,类似于Linux中的select和epoll系统调用。文章将提供详细的代码示例…...
vscode创建flutter项目,运行flutter项目
打开View(查看) > Command Palette...(命令面板)。 可以按下 Ctrl / Cmd Shift P 输入 flutter 选择Flutter: New Project 命令 按下 Enter 。选择Application 选择项目地址 输入项目名称 。按下 Enter 等待项目初始化完成 …...
STM32之CAN外设
相信大家在学习STM32系列的单片机时,在翻阅芯片的数据手册时,都会看到这么一个寄存器外设——CAN外设寄存器。那么,大家知道这个外设的工作原理以及该如何使用吗?这节的内容将会详细介绍STM32上的CAN外设,文章结尾附有…...
【阅读笔记】水果轻微损伤的无损检测技术应用
一、水果轻微损伤检测技术以及应用 无损检测技术顾名思义就是指在不破坏水果样品完整性的情况下对样品进行品质鉴定。目前比较常用的农产品水果类无损检测法有:基于红外热成像、机器视觉技术的图像处理方法、光谱检测技术、介电特性技术检测法等。 1.1 基于红外热…...
Windows服务器IIS部署PHP:FastCGI常见报错排查与修复指南
1. 环境准备与基础配置检查 在Windows Server上部署PHP应用时,IIS与FastCGI的配合就像两个初次见面的陌生人,需要正确的"介绍人"才能顺利沟通。我遇到过太多因为基础环境缺失导致的报错,往往一个简单的复选框就能解决问题。 首先打…...
告别系统休眠困扰:MouseJiggler鼠标模拟工具全解析
告别系统休眠困扰:MouseJiggler鼠标模拟工具全解析 【免费下载链接】mousejiggler Mouse Jiggler is a very simple piece of software whose sole function is to "fake" mouse input to Windows, and jiggle the mouse pointer back and forth. 项目地…...
终极指南:UnityExplorer - 免费高效的Unity游戏运行时调试利器
终极指南:UnityExplorer - 免费高效的Unity游戏运行时调试利器 【免费下载链接】UnityExplorer An in-game UI for exploring, debugging and modifying IL2CPP and Mono Unity games. 项目地址: https://gitcode.com/gh_mirrors/un/UnityExplorer 你是否在U…...
YOLOv8-Pose实战:从Labelme标注到模型训练的数据流水线构建
1. 环境准备与工具安装 在开始构建YOLOv8-Pose数据流水线之前,我们需要准备好开发环境和必要的工具。我推荐使用Python 3.8环境,这个版本在兼容性和稳定性方面表现最好。首先安装Labelme标注工具,这个工具在关键点标注领域几乎是行业标准&am…...
PD-1 Blocking抗体如何重启抗肿瘤免疫?
一、PD-1信号通路在肿瘤免疫中扮演什么角色?PD-1是表达于活化T细胞表面的抑制性受体,其配体PD-L1在多种肿瘤细胞及肿瘤微环境中的抗原呈递细胞上高表达。当PD-1与PD-L1结合后,通过招募SHP-2磷酸酶,抑制T细胞受体及CD28信号通路&am…...
Framework Laptop 13 Pro 发布:升级主板与部件,更重视 Linux 支持
Framework Laptop 13 Pro:升级主板与部件Framework 此次更新最大亮点是配备英特尔酷睿 Ultra 3 系列处理器的升级版主板,它既可以安装到现有的 Framework Laptop 13 中,也能作为新的 Framework Laptop 13 Pro 的一部分购买。同时,…...
从医美祛斑到工业切割:聊聊那些‘跨界’激光器背后的波长秘密(附波长-应用对照表)
从医美祛斑到工业切割:激光波长如何决定它的‘跨界’命运 当你躺在医美诊所接受祛斑治疗时,皮肤科医生使用的694nm红宝石激光,与工厂里切割木板的10.6μm CO2激光,本质上都是同一种技术——它们都遵循爱因斯坦在1917年提出的受激…...
OpenGL Assimp实战:解析并加载嵌入纹理的模型格式(.glb/.gltf)
1. 为什么你的.glb模型加载出来是黑的? 第一次用Assimp加载.glb或.gtf文件时,很多人都会遇到这个经典问题:模型能加载,但显示出来就是一团黑。这其实是因为这类现代3D模型格式采用了纹理嵌入设计,而传统的.obj加载方式…...
YOLOv8性能跃迁:集成可变形注意力机制DAttention的实战指南
1. 为什么YOLOv8需要可变形注意力机制? 目标检测领域近年来最令人头疼的问题之一,就是模型在复杂场景下的表现不稳定。我在实际项目中遇到过这样的情况:同一个检测模型,在空旷场景下mAP能达到85%,但在人群密集的商场监…...
从森林到城市夜间灯光与卫星遥感协同:双碳目标下基于遥感技术的碳库、碳平衡、温室气体、碳循环等多领域监测与模拟
在“双碳”战略目标的宏观背景下,遥感技术作为实现碳库、碳平衡、温室气体及碳循环等多领域精准监测与模拟的关键手段,正迎来前所未有的发展机遇。本研究聚焦于遥感技术在生态系统碳储量估算、碳收支模拟、土地利用碳排放效应监测、能源消耗碳排放空间模…...
