Vue3组件封装技巧与心得
摘要:
日常开发中,用Vue组件进行业务拆分,代码解耦是一个很好的选择;
今天就来分享一下我在使用Vue3进行组件封装的一些技巧和心得,希望能够帮助到大家;
1. 组件特性:
在Vue中组件是一个独立的实例,每个组件都有共通点,就是:属性、插槽、事件、方法;
在日常我们使用第三方组件库的时候,组件库的文档都会说明上面四个特性,而组件封装就是围绕这四个特性进行的;
2. 组件封装:
2.1 组件继承
很多情况下,我们会在一个组件的基础上进行扩展,这个时候就需要用到组件继承;
在Vue2的时候,我们可以使用extends关键字进行组件继承,
但是在Vue3中,extends关键字已经被废弃了;
在Vue3中,如果想要实现组件继承其实很简单,要明白一个组件其实就是一个js对象,我们可以直接将一个组件对象合并
然后注册成一个新的组件;
import { createApp } from "vue";
import App from "./App.vue";
import ElementPlus, { ElInput } from "element-plus";
import "element-plus/dist/index.css";
import { merge } from "lodash";const app = createApp(App);
app.use(ElementPlus);// 组件继承,将ElInput组件的placeholder属性默认值改为"请输入"
app.component("ElInput",merge(ElInput, {props: {placeholder: {default: "请输入"}}})
);app.mount("#app");
这里直接使用了lodash的merge方法,将ElInput组件的props属性进行了合并,然后覆盖注册成了一个新的组件;
因为有很多小伙伴遇到一个问题就是需要固定ElTable组件的一些属性,比如border、stripe、size等,这个时候用这种方法就非常方便;
2.2 组件插槽
上面的组件继承只是简单的改变了组件的默认属性,但是如果我们想要改变组件的结构,就需要用到组件插槽;
通常情况下我们要拆分组件的业务,然后封装成业务组件,这个时候可能会使用到多个组件;
这个时候组件里面有很多组件,需要替换组件里面的组件里面的插槽,这个时候就需要透传插槽;
<!-- 透传插槽 -->
<template><div>区域A这里有一个组件,这个组件需要替换插槽<el-tree :data="treeData"><template v-if="$slots.tree" #default="{ node, data }"><slot name="tree" :node="node" :data="data" /></template></el-tree></div><div>区域B这里有一个组件,这个组件需要替换插槽<el-table :data="tableData"><template v-if="$slots.default"><slot /></template></el-table></div>
</template><script>
export default {data() {return {treeData: new Array(10).fill(0).map((_, index) => ({ label: "label" + index })),tableData: [],};},
};
</script>
通过使用$slots可以获取到组件的插槽,然后通过v-if判断是否有插槽,如果有插槽就进行透传;
除了这种方式之外,还可以使用jsx语法,这种方式更加灵活;
<script lang="jsx">
export default {render() {const areaA = (<div>区域A这里有一个组件,这个组件需要替换插槽<el-tree data={treeData}>{{default: this.$slots.tree}}</el-tree></div>);const areaB = (<div>区域B这里有一个组件,这个组件需要替换插槽<el-table data={tableData}>{{default: this.$slots.default}}</el-table></div>);return (<div>{areaA}{areaB}</div>);}
}
</script>
在setup语法中是没有this的,这个使用需要获取$slots的时候需要使用useSlots方法;
2.3 组件事件和透传 attrs
在Vue2中,我们可以使用$listeners来获取组件的事件,然后进行透传;
而在Vue3中, l i s t e n e r s 已经被废弃了, listeners已经被废弃了, listeners已经被废弃了,listeners和 a t t r s 都被合并到了 attrs都被合并到了 attrs都被合并到了attrs中;
<!-- 组件 -->
<template><div v-bind="$attrs"></div>
</template><!-- 父组件 -->
<template><div><MyComponent class="my-class"@click="handleClick"/></div>
</template>
在Vue3中,我们可以直接使用$attrs来获取组件的事件,然后进行透传;
例如上面的例子,我们可以直接在组件中使用$attrs来获取到class和@click事件,等同于下面的写法;
<!-- 组件 -->
<template><div class="my-class" @click="handleClick"></div>
</template>
但是这里其实有一个小技巧,就是Vue3默认属性是可以透传的,例如上面的例子其实可以简化成下面的写法;
<!-- 组件 -->
<template><div></div>
</template><!-- 父组件 -->
<template><div><MyComponent class="my-class"@click="handleClick"/></div>
</template>
就是组件里面什么都不写,最后在父组件中使用这个组件的时候,属性会透传到组件中的根元素上;
了解这个特性就可以这样封装组件:
<!-- 组件 -->
<template><el-dialog></el-dialog>
</template><!-- 父组件 -->
<template><div><MyComponent v-model="visible"width="500px"/></div>
</template>
通常我们会封装一个Dialog组件来解耦业务,这个时候直接将Dialog作为根元素,然后可以将v-model和width属性透传到Dialog组件上;
这样不需要写Dialog组件开启关闭的双向绑定的代码,前提是不需要在组件内部操作Dialog的开启关闭;
2.4 组件方法
在Vue2中,我们可以通过this.$refs.xxx来获取到组件的实例,然后调用组件的方法;
在Vue3中,我们可以通过ref来获取到组件的实例,然后调用组件的方法;
但是不管是Vue2还是Vue3,在组件内部想要使用组件的子组件的方法都不是一件容易的事情;通常都是手动将组件的实例获取到,然后再重新定义在组件的methods中;
<!-- 组件 -->
<template><div><el-input ref="input" /></div>
</template><script>
export default {methods: {focus() {this.$refs.input.focus();},},
};
</script>
组件的方法通常没有啥特别好的方式,除了我上面的这种方式之外,还有小伙伴是直接将ref返回出去:
<template><div><el-input ref="input" /></div>
</template><script>
export default {methods: {inputRef() {return this.$refs.input},},
};
</script>
当然还有一种偷懒的方式:
<template><div><el-input ref="input" /></div>
</template><script>
export default {mounted() {Object.values(this.$refs.input).forEach((value) => {if (typeof value === 'function') {this[value.name] = (...args) => value(...args);}});},methods: {inputRef() {return this.$refs.input},},
};
</script>
不过这种偷懒的方式只能在options api中使用,因为在composition api中是没有this的;
对于setup语法,如果需要使用组件的方法,可以使用getCurrentInstance来获取到组件的实例,然后将方法挂载到exposed上;
<template><div><el-input ref="input" /></div>
</template><script setup>
import { getCurrentInstance, onMounted, ref } from "vue";const instance = getCurrentInstance();
const input = ref(null);
onMounted(() => {Object.values(input.value).forEach((value) => {if (typeof value === "function") {instance.exposed[value.name] = (...args) => value(...args);}});
});
</script>
这种方式不太稳定,因为exposed是Vue3的一个私有属性,不建议使用;
在setup语法中如果需要暴露组件的内部方法,需要使用defineExpose来暴露;
<script setup>
// ... 省略其他代码defineExpose({focus: () => {input.value.focus();},
});
</script>
3. 总结
这次带来的是Vue3的组件封装的一些技巧,主要是setup语法的一些特性,以及Vue3中的一些奇淫技巧;
Vue3的组件封装相比Vue2来说更加的灵活,但是也更加的复杂,需要我们在使用的时候多加注意;
相关文章:
Vue3组件封装技巧与心得
摘要: 日常开发中,用Vue组件进行业务拆分,代码解耦是一个很好的选择; 今天就来分享一下我在使用Vue3进行组件封装的一些技巧和心得,希望能够帮助到大家; 1. 组件特性: 在Vue中组件是一个独立的…...
15.初识接口1 C#
这是一个用于实验接口的代码 适合初认识接口的人 【CSDN开头介绍】(文心一言AI生成) 在C#编程世界中,接口(Interface)扮演着至关重要的角色,它定义了一组方法,但不提供这些方法的实现。它要求所…...
渗透测试-前端加密分析之RSA加密登录(密钥来源本地)
本文是高级前端加解密与验签实战的第5篇文章,本系列文章实验靶场为Yakit里自带的Vulinbox靶场,本文讲述的是绕过前端RSA加密来爆破登录。 分析 generateKey函数用来生成随机的RSA公私钥 加密的格式如下: {"username":"admin…...
题海拾贝:力扣 86.分隔链表
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞,关注! 1、题…...
《Mycat核心技术》第06章:Mycat问题处理总结
作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 星球项目地址:https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀,…...
前端实现图片压缩
前端实现图片压缩的主要方法有: 使用 HTML5 的 API 利用 canvas 将图片绘制到画布上,然后通过 toDataURL 方法获取压缩后的图片数据。 使用第三方库 借助 compressorjs、browser-image-compression 等开源库,快速实现高质量的图片压缩功能。…...
Python OCR 文字识别
一.引言 文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技…...
怿星科技联合赛力斯举办workshop活动,进一步推动双方合作
12月18日,由怿星科技与赛力斯汽车联合举办的workshop活动在赛力斯五云湖总部展开,双方嘉宾围绕智能汽车发展趋势、行业前沿技术、汽车电子网络与功能测试等核心议题展开了深度对话与交流,并现场参观演示了多套前沿产品。怿星科技CEO潘凯、汽车…...
Vue.js前端框架教程1:Vue应用启动和Vue组件
文章目录 Vue 应用Vue 应用的主要组成部分:启动 Vue 应用:Vue组件基础组件组件注册父子组件组件插槽(Slots)动态组件和 `keep-alive`Vue 应用 Vue 应用由几个主要部分组成,每个部分都有其特定的角色和职责。以下是 Vue 应用的主要组成部分以及如何启动一个 Vue 应用的介绍…...
LabVIEW深海气密采水器测控系统
LabVIEW的深海气密采水器测控系统通过高性价比的硬件选择与自主开发的软件,实现了高精度的温度、盐度和深度测量,并在实际海上试验中得到了有效验证。 项目背景 深海气密采水器是进行海底科学研究的关键工具,用LabVIEW开发了一套测控系统&am…...
SpringBoot 启动类 SpringApplication 二 run方法
配置 在Program arguments配置2个参数:--server.port8081 --spring.profiles.activedev。 run方法 run方法执行结束代表SpringBoot启动完成,即完成加载bean。 // ConfigurableApplicationContext 是IOC容器 public ConfigurableApplicationContext ru…...
【java基础系列】实现一个简单的猜数字小游戏
主要是用的java中的键盘录入和随机数两个api,实现这种人机交互的小游戏,可以用来锻炼基础算法思维 实现效果 实现代码 package com.gaofeng.day10;import java.util.Random; import java.util.Scanner;/*** author gaofeng* date 2024-12-22 - 9:21*/ …...
Liveweb视频融合共享平台在果园农场等项目中的视频监控系统搭建方案
一、背景介绍 在我国的大江南北遍布着各种各样的果园,针对这些地处偏僻的果园及农场等环境,较为传统的安全防范方式是建立围墙,但是仅靠围墙仍然无法阻挡不法分子的有意入侵和破坏,因此为了及时发现和处理一些难以察觉的问题&…...
clickhouse-题库
1、clickhouse介绍以及架构 clickhouse一个分布式列式存储数据库,主要用于在线分析查询 2、列式存储和行式存储有什么区别? 行式存储: 1)、数据是按行存储的 2)、没有建立索引的查询消耗很大的IO 3)、建…...
kafka常用命令
安装kafka注意事项 修改 、vim kafka/config/server.properties 三个地方①brokerId ②logs地址③指定节点 一、创建主题 (必须指定分区,指定副本) #在kafka bin目录下执行以下命令 #①连接hadoop01 创建主题为TEST 分区1 副本3个 bin/ka…...
在 Django 中使用 SMTP 发送邮件是一个常见的需求
在 Django 中使用 SMTP 发送邮件是一个常见的需求,通常用于发送用户注册确认邮件、密码重置邮件等。下面是一个简单的示例,展示了如何在 Django 中配置 SMTP 发送邮件,并创建一个包含表单、路由和视图的界面来发送邮件。 1. 配置 Django 项目…...
JS中的原型与原型链
1. 基本概念 原型(Prototype):每个对象都有一个内部属性 [[Prototype]],通常通过 __proto__ 访问(非标准,但广泛支持)。 原型链(Prototype Chain):对象通过原…...
STM32F407 | Embedded IDE01 - vscode搭建Embedded IDE开发环境(支持JLINK、STLINK、DAPLINK)
导言 Embedded IDE官网:https://em-ide.com/docs/intro 我猜肯定有部分人使用SI Keil开发STM32项目,也有vscode Keil开发STM32程序。SI或vscode编写代码,然后切换Keil编译、下载、调试程序。有一段时间,我也是这么干的。但是,程…...
放弃机器学习框架,如何用Python做物体检测?
每当我们听说“物体检测”时,就会想到机器学习和各种不同的框架。但实际上,我们可以在不使用机器学习或任何其他框架的情况下进行物体检测。在本文中,我将向你展示如何仅使用Python进行操作。 首先,我们定义一个模板图像…...
基于langchain的Agent(实现实时查询天气)
心血来潮,玩一下Agent,实现了多轮对话功能 import requests, jsonfrom langchain.agents import load_tools from langchain.agents import initialize_agent from langchain_community.llms.tongyi import Tongyi from langchain.memory import Conver…...
OB删除1.5亿数据耗费2小时
目录 回顾:mysql是怎么删除数据的? 删除方案 代码实现 执行结果 结论 本篇是实际操作 批量处理数据以及线程池线程数设置 记录学习 背景:有一张用户标签表,存储数据量达4个亿,使用OceanBase存储,由于…...
深度学习之目标检测——RCNN
Selective Search 背景:事先不知道需要检测哪个类别,且候选目标存在层级关系与尺度关系 常规解决方法:穷举法,在原始图片上进行不同尺度不同大小的滑窗,获取每个可能的位置 弊端:计算量大,且尺度不能兼顾 Selective …...
Vue.js前端框架教程7:Vue计算属性和moment.js
文章目录 计算属性(Computed Properties)基本用法缓存机制计算属性 vs 方法使用场景计算属性的 setter 和 getter结论Moment.js 进行时间处理1. 安装 Moment.js2. 在 Vue 组件中引入 Moment.js3. 在全局使用 Moment.js4. 使用 Vue 插件的方式引入 Moment.js5. 常用日期格式化…...
了解RPC
本文来自智谱清言 --------- RPC(Remote Procedure Call,远程过程调用)是一种允许程序调用位于远程计算机上的子程序或服务的技术。这种技术使得构建分布式计算变得更加容易,因为它提供了强大的远程调用能力,同时保持…...
【Go】Go数据类型详解—指针
1. 前言 在我看来,一门编程语言语法的核心就在于数据类型。而各类编程语言的基本数据类型大致相同:int整型、float浮点型、string字符串类型、bool布尔类型,但是在一些进阶数据类型上就有所不同了。本文将会介绍Go语言当中核心的数据类型——…...
C++ 中的智能指针与内存管理:从基础到进阶
在 C 中,内存管理是一个至关重要的课题,尤其是当程序复杂度逐渐增加时。传统的手动内存管理方式(使用 new 和 delete)容易引发内存泄漏、悬挂指针等问题。为了简化内存管理,C11 引入了智能指针(std::unique…...
二、使用langchain搭建RAG:金融问答机器人--数据清洗和切片
选择金融领域的专业文档作为源文件 这里选择 《博金大模型挑战赛-金融千问14b数据集》,这个数据集包含若干公司的年报,我们将利用这个年报搭建金融问答机器人。 具体下载地址 这里 git clone https://www.modelscope.cn/datasets/BJQW14B/bs_challenge_…...
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
1. 上下标 # 注意y轴标签文字 library(ggplot2) ggplot(mtcars, aes(mpg, cyl))geom_point()ylab(label bquote(O[3]~(ug / m^3)))2. 希腊字母,如alpha ggplot(mtcars, aes(mpg, cyl))geom_point()ylab(label bquote(O[3]~(ug / m^3)))ggtitle(expression(alpha))…...
版本更新导致前端网站资源加载失败:Failed to fetch dynamically imported module
前端网站在维护过程中经常有版本更新和重新部署,而这会导致一些问题,其中某些问题会导致更新时,正在网站中的用户无法正常使用。 异常 Failed to fetch dynamically imported module 的诱发原因之一就是版本更新:在用户访问网站的…...
CentOS 7 安装、测试和部署FastDFS
目录 FastDFS环境搭建 安装 libfastcommon 库 安装FastDFS 查看编译后的文件 FastDFS配置 FastDFS启动 启动tracker服务 启动storage服务 查看storage是否已经注册到了tracker下 查看存储文件的目录 FastDFS重启 FastDFS关闭 使用fdfs_test进行测试 修改client.co…...
elasticache备份
Elasticsearch 本地快照操作流程 配置快照存储路径 在 elasticsearch.yml 文件中配置以下字段以指定数据、日志和快照存储路径:path:data: /data/data # 数据存储路径logs: /data/log # 日志存储路径repo: /data/snapshot # 快照存储路径确保路径 /dat…...
wordpress调用指定分类ID下 相同标签的内容
要在WordPress中调用分类ID为1、3、7的分类下,具有相同标签的前10个内容,可以使用自定义的WordPress查询(WP_Query)。以下是实现此功能的步骤和示例代码: 步骤: 确定共同标签: 首先,你需要确定分类1、3、…...
Spring Security 6 系列之五 - 授权管理
之所以想写这一系列,是因为之前工作过程中使用Spring Security,但当时基于spring-boot 2.3.x,其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0,结果一看Spring Security也升级为6.3.0,关键是其风…...
贪心算法求解跳跃游戏
跳跃游戏1: 代码随想录链接:代码随想录 思路: 求解是否能够跳到数组的最后一个位置,关键在于跳跃的覆盖范围 因此设置一个变量表示每次移动时能够覆盖的范围,该变量的初始值为0 因为坐标的位置受到覆盖范围的限制,因此只能遍历覆盖范围内…...
4大应用场景揭秘:AI视频监控在养老院中的智能化管理与安全保障
随着人口老龄化的加剧,养老院的管理面临着越来越多的挑战。传统的人工巡查方式不仅难以做到全天候监控,而且存在响应迟缓、效率低下等问题。为了解决这些问题,AI视频监控系统,利用人工智能技术提供了一种高效、智能化的解决方案。…...
构建简洁之美:我的第一个前端页面
实现界面效果 1. HTML示例代码 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><link rel"stylesheet…...
重拾设计模式--备忘录模式
文章目录 备忘录模式(Memento Pattern)概述定义: 作用:实现状态的保存与恢复支持撤销 / 恢复操作 备忘录模式UML图备忘录模式的结构原发器(Originator):备忘录(Memento)&…...
联通光猫怎么自己改桥接模式?
环境: 联通光猫 ZXHN F677V9 硬件版本号 V9.0 软件版本号 V9.0.0P1T3 问题描述: 联通光猫怎么自己改桥接模式 家里用的是ZXHN F677V9 光猫,最近又搞了个软路由,想改桥接模式 解决方案: 1.拿到最新超级密码&…...
UITableView实现通讯录效果
// // TableViewIndexViewController.m // study2024 // // Created by figo zhu on 2024/12/22. //#import "TableViewIndexViewController.h" //实现协议UITableViewDelegate,UITableViewDataSource interface TableViewIndexViewController ()<UITableView…...
Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用NI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集NI-FGSM介绍背景算法流程 NI-FGSM代码实现NI-FGSM算法实现攻击效果 代码汇总nifgsm.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器: Pytorch | 从零构建AlexNet对CIFAR10进行…...
【Matlab】绘制混淆矩阵示意图+colormap调整方法
主代码 %https://blog.csdn.net/weixin_42943114/article/details/81811556 %https://blog.csdn.net/Mark711/article/details/141144280 clc clear close all warning off %% 原始数据 % 假设groundTruth和predictions是已经定义好的向量 TrueLabels [1 2 1 3 2 3 1 3 2 1 4…...
计算机视觉目标检测——DETR(End-to-End Object Detection with Transformers)
计算机视觉目标检测——DETR(End-to-End Object Detection with Transformers) 文章目录 计算机视觉目标检测——DETR(End-to-End Object Detection with Transformers)摘要Abstract一、DETR算法1. 摘要(Abstract)2. 引言(Introduction&#…...
资源型数字化平台该如何顺利运营?
一、引言 随着信息技术的迅猛发展,资源型数字化平台在各领域的重要性日益凸显。此类平台整合各类资源,以数字化手段提升资源利用效率与价值,但确保其顺利运营面临诸多挑战。 二、资源型数字化平台特点 资源型数字化平台具有资源整合性&…...
写SQL太麻烦?免费搭建 Text2SQL 应用,智能写 SQL | OceanBase AI 实践
自OceanBase 4.3.3版本推出以来,向量检索的能力受到了很多客户的关注,也纷纷表达希望OB能拓展更多 多模数据库大模型 的AI应用实践。 在上篇文章 👉 OceanBase LLM,免费构建你的专属 AI 助手 ,我们介绍了如何去搭建一…...
Linux系统编程——系统内核中的信号
目录 一、前言 二、系统内核中的信号 三、sigset_t 四、信号集操作 1、sigpending(); 2、sigemptyset(); 3、sigfillset(sigset_t *set); 4、int sigaddset ()和sigdelset() 编辑 5、sigismember() 6、sigprocmask() 五、信号集操作代码演示 六、深入理解进程的信…...
Mapbox-GL 中 `token` 的使用
Mapbox-GL 是一个开源的 JavaScript 库,允许开发者在网页上渲染交互式地图。token 在 Mapbox 中主要是指 access token,它用于身份验证和授权,确保应用程序能够访问 Mapbox 的地图服务。 下面详细解析 Mapbox GL 中 token 的使用,…...
PostgreSQL标识符长度限制不能超过63字节
文章目录 问题:标识符太长会被截断分析相关源码可以尝试以下案例 问题:标识符太长会被截断 在创建表时,发现表名太长会自动被截断,导致查询表时报错了。 分析 参考:https://www.postgresql.org/docs/current/limits…...
【Token】校验、会话技术、登录请求、拦截器【期末实训】实战项目学生和班级管理系统\Day15-后端Web实战(登录认证)\讲义
登录认证 在前面的课程中,我们已经实现了部门管理、员工管理的基本功能,但是大家会发现,我们并没有登录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,所以我们今天的主题就是登录认证。 最终我们要实现…...
电机相关内容
文章目录 电枢电阻电动机电动势系数负载转矩直流电动机的角速度和速度关系 电枢电阻 电枢电阻的计算公式如下: 基于欧姆定律的公式: R a V a − V b I a R_a \frac{V_a - V_b}{I_a} RaIaVa−Vb 其中, ( V a ) (V_a) (Va…...
电商环境下的财务ERP系统架构
先介绍一下自己的工作经历,2002年开始进入ERP实施行业,专注于O记EBS系统,正好赶上中国经济和信息化高度发展的阶段,先后实施过很多大国企和民企的大型ERP项目,在实施过程中逐渐对ERP系统的架构、模块设计有更深入的认识…...