vue3常用的组件间通信
一 props
props 可以实现父子组件通信,props数据是只读。
1. 基本用法
在父组件中,你可以这样传递 props:
<template><ChildComponent message="Hello, Vue 3!" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';
</script>
在 Vue 3 的 <script setup>
语法中,你可以使用 defineProps 来定义 props:
<script setup>
import { defineProps } from 'vue';const props = defineProps({title: String,count: Number
});
</script>
在传统的 export default 语法中,可以这样定义:
export default {props: {title: {type: String,required: true},count: {type: Number,default: 0}}
};
2. 类型和默认值
- 类型:确保传递给组件的 props 类型正确,Vue 会进行类型检查。
const props = defineProps({title: String, // 只接受字符串count: {type: Number, // 只接受数字default: 0 // 默认值}
});
- 默认值:如果没有提供 props,组件将使用定义的默认值。
const props = defineProps({count: {type: Number,default: 0}
});
3. 组件的 props 验证
你可以定义自定义验证逻辑:
const props = defineProps({age: {type: Number,validator: value => value >= 18 // 只接受18岁及以上}
});
4. 注意事项
- 不可变性:props 是只读的,子组件不能直接修改父组件传递过来的 props。如果需要修改,应该在子组件内部创建一个本地副本:
<script setup>
import { ref, computed } from 'vue';const props = defineProps(['count']);
const localCount = ref(props.count);const increment = () => {localCount.value++;
};
</script>
- 响应式:如果 props 是对象或数组,确保你在子组件中使用时能够保持其响应性。
- 性能考虑:如果传递的 props是大型数据结构,如数组或对象,确保你的组件能够有效地处理这些数据。避免在子组件中直接进行深度操作,以防止性能问题。
- 组件封装:合理使用 props 有助于组件的封装和复用,保持组件的单一职责和可测试性。
二 自定义事件
自定义事件用于在子组件和父组件之间传递信息
1. 在子组件中触发事件
使用 emit 方法触发自定义事件:
<script setup>
import { defineEmits } from 'vue';const emit = defineEmits(['my-event']);const triggerEvent = () => {emit('my-event', 'Hello from child');
};
</script><template><button @click="triggerEvent">Trigger Event</button>
</template>
2. 在父组件中监听事件
使用 v-on 或简写 @ 监听自定义事件:
<template><ChildComponent @my-event="handleMyEvent" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';const handleMyEvent = (message) => {console.log(message); // 输出 "Hello from child"
};
</script>
3. 事件参数
子组件触发的事件可以带有参数,这些参数会传递给父组件的事件处理函数。可以传递任意类型的数据(如字符串、数字、对象等)。
// 子组件
const triggerEvent = () => {emit('my-event', 'Hello from child', 123);
};// 父组件
const handleMyEvent = (message, number) => {console.log(message, number); // 输出 "Hello from child" 123
};
4 组件解耦
子组件应通过自定义事件向父组件发送消息,而不是直接修改父组件的数据。这样可以保持组件的独立性和可重用性。
<!-- 子组件 -->
<template><button @click="notifyParent">Notify Parent</button>
</template><script setup>
import { defineEmits } from 'vue';
const emit = defineEmits(['notify']);const notifyParent = () => {emit('notify', 'Data');
};
</script><!-- 父组件 -->
<template><ChildComponent @notify="handleNotify" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';const handleNotify = (data) => {console.log(data); // 输出 "Data"
};
</script>
三 v-model
在 Vue 3 中,v-model 的原理基于双向数据绑定。其核心是通过 modelValue
和 update:modelValue
事件来实现的。具体来说:
- 父组件:使用 v-model 绑定到子组件的
modelValue
属性。 - 子组件:通过
modelValue
属性接收数据,并在需要时通过emit('update:modelValue', newValue)
触发更新事件,将新值传递回父组件。
在 Vue 3 中,v-model 的默认行为可以被自定义,允许为不同的 props 和事件指定不同的名称。可以通过 v-model:propName
和 @update:propName
的方式来指定。
1 原理
v-model 实现了双向绑定,其底层机制涉及两个主要的部分:
- 数据绑定:v-model 将父组件的一个数据属性绑定到子组件的 modelValue 属性。
- 事件更新:子组件通过触发 update:modelValue 事件来通知父组件更新数据属性。
- 简化流程示意:
- 数据绑定:
<ChildComponent v-model="parentValue" />
在这个例子中,parentValue 是父组件的数据属性,v-model 将其绑定到ChildComponent 组件的 modelValue 属性上。
- 数据传递:
<input :value="modelValue" @input="updateValue" />
子组件的 input 元素将 modelValue 作为其值,并监听 input 事件。
- 事件触发:
function updateValue(event) {emit('update:modelValue', event.target.value);
}
当用户在输入框中输入内容时,子组件触发 update:modelValue 事件,将新的值传递给父组件。
2 基本用法:
在父组件中使用 v-model 绑定数据到子组件的 props 中,子组件通过 emit 触发更新:
父组件
<template><ChildComponent v-model:message="parentMessage" />
</template><script setup>
import { ref } from 'vue';
const parentMessage = ref('Hello World');
</script>
子组件
<template><input :value="message" @input="$emit('update:message', $event)" />
</template><script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps(['message']);
const emit = defineEmits();
</script>
3 自定义 v-model:
Vue 3 允许自定义 v-model 的 prop 名称:
父组件
<template><CustomComponent v-model:customProp="value" />
</template><script setup>
import { ref } from 'vue';
const value = ref('Hello');
</script>
子组件
<template><input :value="customProp" @input="$emit('update:customProp', $event)" />
</template><script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps(['customProp']);
const emit = defineEmits();
</script>
4 多个 v-model:
支持在一个组件上使用多个 v-model:
父组件
<template><MultipleModelComponent v-model:title="title" v-model:content="content" />
</template><script setup>
import { ref } from 'vue';
const title = ref('Title');
const content = ref('Content');
</script>
子组件
<template><input :value="title" @input="$emit('update:title', $event)" /><textarea :value="content" @input="$emit('update:content', $event)" />
</template><script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps(['title', 'content']);
const emit = defineEmits();
</script>
四 provide 和 inject
在 Vue 3 中,provide 和 inject 是用来在组件层级中共享数据的一种机制。它们特别适用于跨级传递数据,而不需要通过每一级的 props 和事件传递。这种机制适合于较复杂的应用场景,比如主题配置、用户认证状态等。
1 provide 和 inject 的基本用法
1. provide 和 inject 的作用
- provide: 在父组件中定义,可以将数据提供给其所有子组件(包括嵌套的子组件)。
- inject: 在子组件中定义,用于接收从祖先组件提供的数据。
父组件:使用 provide 提供数据
<template><div><h1>Parent Component</h1><child-component /></div>
</template><script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';const data = 'Shared Data';
provide('sharedData', data); // 提供数据
</script>
在这个父组件中,我们使用 provide 传递了一个名为 ‘sharedData’ 的数据,所有子组件(及其嵌套的子组件)都可以通过 inject 来访问这个数据。
子组件:使用 inject 接收数据
<template><div><h2>Child Component</h2><p>{{ sharedData }}</p></div>
</template><script setup>
import { inject } from 'vue';const sharedData = inject('sharedData'); // 接收数据
</script>
在这个子组件中,我们使用 inject 来接收从父组件中提供的数据 ‘sharedData’,并可以在模板中使用它。
2 provide 和 inject 的进阶用法
1. 提供响应式数据
提供响应式数据(如 ref 或 reactive),使得数据在多个组件中保持同步。
<template><div><h1>Parent Component</h1><child-component /></div>
</template><script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const count = ref(0);
provide('count', count); // 提供响应式数据
</script>
在子组件中,你可以直接修改和使用这个响应式数据:
<template><div><h2>Child Component</h2><p>Count: {{ count }}</p><button @click="count++">Increment</button></div>
</template><script setup>
import { inject } from 'vue';const count = inject('count'); // 接收响应式数据
</script>
2. 使用 provide 和 inject 进行依赖注入
对于较复杂的应用,可以在多个组件之间共享更复杂的对象或函数。例如,可以用来注入服务或工具函数。
<template><div><h1>App Component</h1><child-component /></div>
</template><script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';const apiService = {fetchData() {return 'Data from API';}
};provide('apiService', apiService); // 提供服务
</script>
在子组件中,你可以注入并使用这个服务:
<template><div><h2>Child Component</h2><p>{{ data }}</p></div>
</template><script setup>
import { inject } from 'vue';const apiService = inject('apiService');const data = apiService.fetchData(); // 使用服务
</script>
3 总结
- provide: 在父组件中定义,用来提供数据或服务给其所有子组件。
- inject: 在子组件中定义,用来接收从父组件提供的数据或服务。
- 可以使用响应式数据来确保跨组件的状态同步。
- 适用于复杂的应用程序中需要跨组件传递和共享数据的场景。
- provide 和 inject 是 Vue 3 强大的功能之一,能够帮助你更灵活地管理组件之间的状态和依赖。
五 refs
$refs 是 Vue.js 提供的一种机制,用于直接访问 DOM 元素或子组件实例。你可以在模板中使用 ref 特性来为 DOM 元素或组件指定一个引用名,然后在 Vue 实例或组件的代码中通过 $refs 来访问这些引用。
在 Vue 3 中,使用 ref 访问子组件时,通常需要通过 expose 来暴露一些方法或数据,以便父组件能够访问。你需要在子组件中使用defineExpose 来明确暴露的内容。这样,父组件就可以直接通过 ref 获取到这些数据或方法
- 用法
- 访问 DOM 元素
<template><input ref="myInput" type="text" /><button @click="focusInput">Focus Input</button>
</template><script setup>
import { ref, onMounted } from 'vue';const myInput = ref(null);const focusInput = () => {myInput.value.focus(); // 访问并操作 DOM 元素
};onMounted(() => {console.log(myInput.value); // 在组件挂载后访问 DOM 元素
});
</script>
- 访问子组件实例
子组件:
在子组件中使用 defineExpose 来暴露你想要的数据或方法。例如:
<template><div>{{ internalValue }}</div>
</template><script setup>
import { ref, defineExpose } from 'vue';const internalValue = ref('Hello, World!');defineExpose({internalValue
});
</script>
父组件:
在父组件中使用 ref 获取子组件的实例,然后访问暴露的数据或方法:
<template><ChildComponent ref="child" /><button @click="showValue">Show Value</button>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const child = ref(null);const showValue = () => {alert(child.value.internalValue);
};
</script>
- 优缺点
优点:
- 直接访问 DOM 元素或子组件实例,适用于需要直接操作或获取 DOM 元素或组件的方法。
- 可以在组件初始化后执行 DOM 操作,避免了过早访问 DOM 元素的问题。
缺点:
- 过度使用 ref 可能会使组件的耦合度变高,使组件之间的关系变得复杂。
- 不应过多依赖 ref 来解决问题,应该优先考虑使用 props 和 events 进行数据传递和事件处理。
相关文章:
vue3常用的组件间通信
一 props props 可以实现父子组件通信,props数据是只读。 1. 基本用法 在父组件中,你可以这样传递 props: <template><ChildComponent message"Hello, Vue 3!" /> </template><script setup> import C…...
Windows 查找特定进程的ID并杀死
"*分析用户信息.py*" 换为自己的文件名 Get-WmiObject Win32_Process | Where-Object { $_.CommandLine -like "*分析用户信息.py*" } 查找后 内容如下 __GENUS : 2 __CLASS : Win32_Process __SUPERCLASS …...

Snapchat API 访问:Objective-C 实现示例
Snapchat 是一个流行的社交媒体平台,它允许用户发送和接收短暂存在的图片和视频。对于开发者来说,访问 Snapchat API 可以为应用程序添加独特的社交功能。本文将介绍如何在 Objective-C 中实现对 Snapchat API 的访问,并提供一个详细的代码示…...

ps证件照蓝底换白底
ps证件照蓝底换白底 1、打开 Photoshop,导入需要处理的照片。 2、左侧工具栏中选择“魔棒工具”,点击证件照的背景区域进行选择。 3、使用快捷键 Shift F5 或者从顶部菜单选择“编辑” -> “填充”,在弹出的对话框中选择“填充内容”中…...

阿里云kafka消息写入topic失败
1. 问题现象描述 20240918,14:22,测试反馈说kafka有问题,生产者写入消息的时候报错,并发了一张日志截图,主要报错如下: to topic xxxx: org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for x…...

图像放大效果示例【JavaScript】
实现效果: 当鼠标悬停在小图(缩略图)上时,大图(预览图)会随之更新为相应的小图,并高亮当前悬浮的小图的父元素。 代码: 1. HTML部分 <!DOCTYPE html> <html lang"z…...
【C#生态园】云端之C#:全面解析6种云服务提供商的SDK
C#开发者必读:深度比较6种云服务SDK 前言 随着云计算技术的迅猛发展,越来越多的企业和开发者选择将应用程序部署到公共云平台上。针对C#开发者而言,各大云服务提供商纷纷推出了适用于C#的SDK,以便开发者能够更轻松地与其云服务进…...

远程升级又双叒叕失败?背后原因竟然是。。。
最近又遇到了远程升级接连失败的情况,耐心和信心都备受折磨! 事情是这样的:有客户反馈在乡村里频繁出现掉线的情况,不敢耽搁,赶紧联系小伙伴排查测试,最后发现,只有去年某一批模块在当下环境才…...

【测试】——Selenium API (万字详解)
📖 前言:本文详细介绍了如何利用Selenium进行Web自动化测试,包括定位元素(如cssSelector和xpath)、常用操作函数(如点击、输入等)、窗口管理、键盘鼠标事件和浏览器导航,以及处理弹窗…...

Redis:原理+项目实战——Redis实战3(Redis缓存最佳实践(问题解析+高级实现))
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理项目实战——Redis实战2(Redis实现短信登录(原理剖析代码优化)&#x…...

刚刚,Stable Diffusion 2024升级,最强Ai绘画整合包、部署教程(解压即用)
2024Ai技术大爆发的元年 目前两款Ai神器大火 一款是大名鼎鼎的Chat GPT 另外一款—Stable Diffusion 堪称全球最强Ai绘画工具 Stable Diffusion Ai绘画2024版本更新啦! 从4.8.7更新至**4.9版本!**更新优化和大模型增加,无需安装…...

【AIGC】ChatGPT提示词助力高效文献处理、公文撰写、会议纪要与视频总结
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯高效英文文献阅读提示词使用方法 💯高效公文写作提示词使用方法 💯高效会议纪要提示词使用方法 💯高效视频内容分析提示词使用方法 &a…...
centos7更换国内下载源
📖centos7更换国内下载源 在CentOS 7上更换为国内源可以通过替换 /etc/yum.repos.d/CentOS-Base.repo文件来实现。以下是一些常用的国内源以及如何更换的示例: 阿里云源: mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Bas…...

【Linux】常用指令【更详细,带实操】
Linux全套讲解系列,参考视频-B站韩顺平,本文的讲解更为详细 目录 一、文件目录指令 1、cd【change directory】指令 2、mkdir【make dir..】指令 3、cp【copy】指令 4、rm【remove】指令 5、mv【move】指令 6、cat指令和more指令 7、less和…...
力扣3290.最高乘法得分
力扣3290.最高乘法得分 递归 记忆化搜索 对于b数组,从右往左考虑取不取,如果取则问题变成b[0] ~ b[i-1]间找j - 1个数 如果不取,则问题变成b[0] ~ b[i]间找j个数即dfs(i,j) max(dfs(i-1,j) , dfs(i-1,j-1) a[j] * b[i]) 边界:…...

Python | Leetcode Python题解之第413题等差数列划分
题目: 题解: class Solution:def numberOfArithmeticSlices(self, nums: List[int]) -> int:n len(nums)if n 1:return 0d, t nums[0] - nums[1], 0ans 0# 因为等差数列的长度至少为 3,所以可以从 i2 开始枚举for i in range(2, n):i…...
深入理解 ClickHouse 的性能调优与最佳实践
1. 介绍 ClickHouse 是一款由 Yandex 开发的开源列式数据库,专为在线分析处理(OLAP)场景设计。它以极高的查询性能著称,尤其适用于大规模数据的快速聚合和分析。自发布以来,ClickHouse 在多个行业中得到了广泛应用&am…...

Elasticsearch——介绍、安装与初步使用
目录 1.初识 Elasticsearch1.1.了解 ES1.1.1.Elasticsearch 的作用1.1.2.ELK技术栈1.1.3.Elasticsearch 和 Lucene1.1.4.为什么不是其他搜索技术?1.1.5.总结 1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排 1.3.Elasticsearch 的一些概念1.3.1.文档和字…...
FreeRTOS保姆级教程(以STM32为例)—任务创建和任务控制API说明
目录 一、任务创建: (1)TaskHandle_t 任务句柄 (2) xTaskCreate: 函数原型: 参数说明: 返回值: 示例: 注意事项: 用法示例:…...
Go语言现代web开发14 协程和管道
概述 Concurrency is a paradigm where different parts of the program can be executed in parallel without impact on the final result. Go programming supports several concurrency concepts related to concurrent execution and communication between concurrent e…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...