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…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...
Springboot 高校报修与互助平台小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,高校报修与互助平台小程序被用户普遍使用,为…...
运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.
报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符,最后运行:npm run lint --fix...
【R语言编程——数据调用】
这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中,有多个库支持调用内置数据集或外部数据,包括studentdata等教学或示例数据集。以下是常见的库和方法: 可用库及数据集 openintro库 该库包含多个教学数据集&a…...
