Vue 系列之:组件通讯
子组件调用父组件方法
1、直接在子组件中通过 this.$parent.event 来调用父组件的方法
父组件:
<template><p><child></child></p>
</template>
<script>import child from './child';export default {components: {child},methods: {fatherMethod() {console.log('测试');}}};
</script>
子组件:
<template><p><button @click="childMethod()">点击</button></p>
</template>
<script>export default {methods: {childMethod() {this.$parent.fatherMethod();}}};
</script>
2、父组件使用 v-on 监听事件,子组件使用 $emit 件触发事件
@ 是 v-on 的缩写
父组件:
<template><p><child @method1="fatherMethod"></child></p>
</template>
<script>import child from './child';export default {components: {child},methods: {fatherMethod(params) {console.log('测试', params);}}};
</script>
子组件:
<template><p><button @click="childMethod()">点击</button></p>
</template>
<script>export default {methods: {childMethod() {this.$emit('method1', params); // params 为参数,可不传 // this.$emit('method1');}}};
</script>
3、父组使用 v-bind 绑定事件,子组件用 props 接收事件
: 是 v-bind 的缩写
父组件:
<template><p><child :method1="fatherMethod"></child></p>
</template>
<script>import child from './child';export default {components: {child},methods: {fatherMethod() {console.log('测试');}}};
</script>
子组件:
<template><p><button @click="childMethod()">点击</button></p>
</template>
<script>export default {props: {method1: {type: Function,default: null}},methods: {childMethod() {if (this.method1) {this.method1();}}}};
</script>
父组件调用子组件方法
1、通过 ref 直接调用子组件的方法
父组件:
<template><div><Button @click="fatherMethod">点击调用子组件方法</Button><Child ref="child"/></div>
</template> <script>
import Child from './child';
export default {methods: {fatherMethod() {this.$refs.child.childMethod();},},
}
</script>
子组件:
<template><div>我是子组件</div>
</template><script>
export default {methods: {childMethod() {console.log('我是子组件的方法');},},
};</script>
2、通过组件的$emit、$on方法(可以,但是没必要)
父组件:
<template><div><Button @click="fatherMethod">点击调用子组件方法</Button><Child ref="child"/></div>
</template> <script>
import Child from './child';
export default {methods: {fatherMethod() {this.$refs.child.$emit("getChildMethod") //子组件$on中的名字},},
}
</script>
子组件:
<template><div>我是子组件</div>
</template><script>
export default {mounted() {this.$nextTick(function() {this.$on('getChildMethod', this.childMethod);});},methods: {childMethod() {console.log('我是子组件方法');}}
};
</script>
兄弟组件
-
方法1:通过父组件作为中转
-
通过 ref 和 $parent
-
通过 provide 和 inject
-
-
方法2:使用 EventBus 事件总线
-
方法3:vuex,下一篇内容会讲
EventBus 使用方式
1、初始化——全局定义
可以将 eventBus 绑定到 vue 实例的原型上,也可以直接绑定到 window 对象上
//main.js//注册方式一
Vue.prototype.$EventBus = new Vue();//注册方式二
window.EventBus = new Vue();
2、监听事件
//使用方式一
this.$EventBus.$on('eventName', (param1, param2, ...) => {//需要执行的代码
})//使用方式二
EventBus.$on('eventName', (param1, param2, ...) => {//需要执行的代码
})
3、触发事件
//使用方式一
this.$EventBus.$emit('eventName', param1, param2,...)//使用方式二
EventBus.$emit('eventName', param1, param2,...)
4、移除监听事件
为了避免在监听时,事件被反复触发,通常需要在页面销毁时移除事件监听。或者在开发过程中,由于热更新,事件可能会被多次绑定监听,这时也需要移除事件监听。
//使用方式一
this.$EventBus.$off('eventName');//使用方式二
EventBus.$off('eventName');//移除所有
EventBus.$off();
5、示例
简单示例一:
<!--组件 A.vue-->
<script>
export default { mounted() { // 监听事件this.$EventBus.$on('custom-event', this.handleEvent) }, methods: { handleEvent(data) { console.log(data) } }
}
</script><!--组件 B.vue-->
<template> <button @click="handleClick">触发事件</button>
</template> <script>
export default {data() {return {str: '我来自 B 组件'}}methods: {handleClick() {// 触发事件this.$EventBus.$emit('custom-event', this.str) } }
}
</script>
示例二:
假设兄弟组件有三个,分别是 A、B、C 组件,A 组件如何获取 B 或者 C 组件的数据
这时候就可以使用 EventBus。EventBus 是一种发布/订阅模式,用于在组件之间传递事件和数据。A 组件可以监听由 B 或 C 组件发布的事件,并在事件处理函数中获取传递的数据。
思路:
A 组件中使用 Event.$on 监听事件
B、C 组件中使用 Event.$emit 触发事件
// A.vue
<template> <div>A 接收到的数据: {{ receivedData }}</div>
</template> <script> export default { data() { return { receivedData: null }; }, mounted() { // 监听事件 EventBus.$on('custom-event', (data) => { this.receivedData = data.message; }); }, beforeDestroy() { // 组件销毁前,移除事件监听器 EventBus.$off('custom-event'); }
};
</script>
// B.vue 和 C.vue
<template> <button @click="sendData">发送数据</button>
</template> <script>
export default { methods: {sendData() { const data = { message: 'I am from B' };// 触发事件EventBus.$emit('data-from-a', data); } }
};
</script>
多层组件(爷孙)
provide() 和 inject[]
用于将数据或方法暴露给组件树中的任何后代组件,哪怕是深层次的后代组件都可以访问到这些数据,而无需通过 props 层层传递。
注意:provide 和 inject 主要用于单向数据传递,即从祖先组件流向后代组件。虽然可以在后代组件中修改注入的数据,但这种做法会破坏单向数据流的原则,导致数据流向不清晰,难以调试,因此不建议这样做。
Vue2 用法:
<!--爷/父 组件-->
<template><div id="app"><Children></Children></div>
</template><script>
import Children from "./Children.vue";
export default {name: 'parent',components: { Children },provide() {return {parentEvent: this.myEvent,parentData: this.message,parentStr: '字符串数据'};},data() {return {message: 'data中的数据'}},methods: {myEvent(params1, params2) {console.log(params1, params2)},}
};
</script>
<!--子/孙 组件-->
<template><el-button @click="handleClick">测试</el-button>
</template><script>
export default {name: 'child',inject: ["parentEvent", "parentData", "parentStr"],methods: {handleClick() {this.parentEvent('参数1', '参数2');console.log(this.parentData)console.log(this.parentStr)}}
};
</script>
从上到下依次打印:
参数1 参数2
data中的数据
字符串数据
Vue3 用法:
<!--爷/父 组件-->
<template><div id="app"><Children></Children></div>
</template><script setup>
import { ref, provide } from "vue";
import Children from "./Children.vue";
const message = ref('data中的数据');
const str = '字符串数据'
function myEvent(params1, params2) {console.log(params1, params2)
}
provide('parentEvent', myEvent);
provide('parentData', message);
provide('parentStr', str);
</script>
<!--子/孙 组件-->
<template><el-button @click="handleClick">测试</el-button>
</template><script setup>
import { inject } from "vue";
const parentEvent = inject('parentEvent');
const parentData = inject('parentData');
const parentStr = inject('parentStr', '默认值');function handleClick() {parentEvent('参数1', '参数2')console.log(parentData.value)console.log(parentStr)
}
</script>
细心的朋友已经发现:在 Vue3 中,子组件打印的是 parentData.value,这说明 parentData 是一个响应式对象。
直接总结:
| 特性 | Vue2 | Vue3 |
|---|---|---|
| 响应式支持 | provide 提供的数据不是响应式的 | provide 提供的数据是响应式的 |
| 默认值支持 | 不支持默认值 | 支持默认值,inject 的第二个参数就是默认值 |
$attrs 和 $listeners
$attrs
$attrs 是一个对象,包含了父组件传递给子组件的所有非 prop 属性(即没有在 props 中定义的属性)。
当你希望将父组件传递的属性传递给子组件的子组件时,可以使用 $attrs。
父组件:
<!-- 父组件 -->
<template><div id="app"><Children :params1="params1" :params2="params2" /></div>
</template><script>
import Children from "./Children.vue";
export default {name: 'parent',components: { Children },data() {return {params1: '测试1',params2: '测试2',params3: '测试3',}},mounted() {setTimeout(() => {this.params2 += 'timeout'}, 5000);},
};
</script>
子组件:
<!-- 子组件 -->
<template><div><p>params1: {{ $attrs.params1 }}</p><p>params2: {{ $attrs.params2 }}</p><p>params3: {{ $attrs.params3 }}</p><Groundson v-bind="$attrs" :params4="params4"/></div>
</template><script>
import Groundson from "./Groundson.vue";
export default {name: 'children',components: { Groundson },props: {params1: {type: String,default: ""}},data() {return {params4: '测试4'}},mounted() {console.log("children $attrs:", this.$attrs);},
};
</script>
孙组件:
<!-- 孙组件 -->
<template><div></div>
</template>
<script>export default {name: 'groundson',mounted() {console.log("groundson $attrs:", this.$attrs);},
};
</script>
页面:

打印:

总结:
-
没有通过 v-bind 传递给子组件的,子组件的 $attrs 中不会有该属性
-
通过 v-bind 传递给了子组件,但是子组件使用了 props 接收的,子组件的 $attrs 中不会有该属性
-
$attrs 中的属性值是响应式的
-
在子组件中使用 v-bind=“$attrs” 可以将子组件的 $attrs 中的所有属性都传递给孙子组件,孙子组件也是按同样的规则接收
inheritAttrs 的作用:
观察页面元素发现:

子组件的根元素和孙子组件的根元素都多了一些属性
官方解释:默认情况下,父组件传递的,但没有被子组件解析为 props 的 attributes 绑定会被“透传”。这意味着当我们有一个单根节点的子组件时,这些绑定会被作为一个常规的 HTML attribute 应用在子组件的根节点元素上。我们可以通过设置 inheritAttrs 为 false 来禁用这个默认行为。
例如在子组件中加上 inheritAttrs: false:

子组件根节点的属性消失了,由于没有在孙子组件中设置,孙子组件的根节点还保留着属性
$listeners
$listeners 包含了父组件传递给子组件的所有事件监听器(即 v-on 绑定的事件)。
与 $attrs 类似, $attrs 是传递属性, $listeners 是传递方法。这里就不再举例了。
注意:在 Vue3 中,$listeners 已经被移除,其功能被合并到了 $attrs 中。
相关文章:
Vue 系列之:组件通讯
子组件调用父组件方法 1、直接在子组件中通过 this.$parent.event 来调用父组件的方法 父组件: <template><p><child></child></p> </template> <script>import child from ./child;export default {components: {chi…...
【Linux实践系列】:用c语言实现一个shell外壳程序
🔥本文专栏:Linux Linux实践项目 🌸博主主页:努力努力再努力wz 那么今天我们就要进入Linux的实践环节,那么我们之前学习了进程控制相关的几个知识点,比如进程的终止以及进程的等待和进程的替换,…...
STL map 的 lower_bound(x)、upper_bound(x) 等常用函数
【STL map 简介】 ● STL map 是一种关联容器,存储键值对,每个键(key value)是唯一的,而值(mapped value)可以重复。构建 STL map 时,无论元素插入顺序如何,STL map 中的…...
【A2DP】SBC 编解码器互操作性要求详解
目录 一、SBC编解码器互操作性概述 二、编解码器特定信息元素(Codec Specific Information Elements) 2.1 采样频率(Sampling Frequency) 2.2 声道模式(Channel Mode) 2.3 块长度(Block Length) 2.4 子带数量(Subbands) 2.5 分配方法(Allocation Method) 2…...
Computational Linguistics期刊全解析:领域顶刊的投稿指南与学术价值
在人工智能与语言学交叉融合的浪潮中,《Computational Linguistics》(CL)作为该领域的标杆期刊,始终是研究者发表前沿成果的首选平台。本文将从期刊影响力、投稿策略、收稿方向等角度,为学者提供一份全面的指南。 一、…...
【量化科普】Sharpe Ratio,夏普比率
【量化科普】Sharpe Ratio,夏普比率 🚀量化软件开通 🚀量化实战教程 在量化投资领域,夏普比率(Sharpe Ratio)是一个非常重要的风险调整后收益指标。它由诺贝尔经济学奖得主威廉F夏普(William…...
运行OpenManus项目(使用Conda)
部署本项目需要具备一定的基础:Linux基础、需要安装好Anaconda/Miniforge(Python可以不装好,直接新建虚拟环境的时候装好即可),如果不装Anaconda或者Miniforge,只装过Python,需要确保Python是3.…...
TikTok Shop欧洲市场爆发,欧洲TikTok 运营网络专线成运营关键
TikTok在欧洲的影响力还在持续攀升,日前,TikTok发布了最新的欧盟执行和使用数据报告,报告中提到: 2024年7~12月期间,TikTok在欧盟地区的月活用户达1.591亿,较上一报告期(2024年10月发布…...
基于YOLO11深度学习的电瓶车进电梯检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
计算机毕业设计SpringBoot+Vue.js制造装备物联及生产管理ERP系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
微服务保护:Sentinel
home | Sentinelhttps://sentinelguard.io/zh-cn/ 微服务保护的方案有很多,比如: 请求限流 线程隔离 服务熔断 服务故障最重要原因,就是并发太高!解决了这个问题,就能避免大部分故障。当然,接口的并发…...
labelimg标注的xml标签转换为yolo格式标签
本文不生产技术,只做技术的搬运工!!! 前言 在yolo训练时,我们需要对图像进行标注,而使用labelimg标注时如果直接选择输出yolo格式的数据集,则原始数据的很多信息无法被保存,因此一版…...
VUE3开发-9、axios前后端跨域问题解决方案
VUE前端解决跨域问题 前端页面需要改写 如果无效,记得重启服务器 后端c#解决跨域问题 前端js取值,后端c#跨域_c# js跨域-CSDN博客...
机试准备第12天
首先学习队列,队列有先进先出的特性。广度优先遍历需要基于队列实现,C中的stl引入了队列的实现方式。队列支持push(),进入队尾,pop()出队,队头出队,front()获取队首元素,back()获取队尾元素&…...
计算机二级MS之PPT
声明:跟着大猫和小黑学习随便记下一些笔记供大家参考,二级考试之前将持续更新,希望大家二级都能轻轻松松过啦,过了二级的大神也可以在评论区留言给点建议,感谢大家!! 文章目录 考题难点1cm25px…...
伊藤积分(Ito Integral):随机世界中的积分魔法
伊藤积分(Ito Integral):随机世界中的积分魔法 在研究随机微分方程(SDE)和布朗运动时,伊藤积分(Ito Integral)是一个绕不开的关键概念。它是处理布朗运动随机项 ( d W ( t ) dW(t)…...
【Deepseek应用】Zotero+Deepseek 阅读和分析文献(下)
【Deepseek应用】Deepseek R1 本地部署(OllamaDockerOpenWebUI) 【Deepseek应用】ZoteroDeepseek 阅读和分析文献(上) 【Deepseek应用】ZoteroDeepseek 阅读和分析文献(下) 使用邀请码 cXfb9wOT 注册 硅基流…...
人工智能与深度学习的应用案例:从技术原理到实践创新
第一章 引言 人工智能(AI)作为21世纪最具变革性的技术之一,正通过深度学习(Deep Learning)等核心技术推动各行业的智能化进程。从计算机视觉到自然语言处理,从医疗诊断到工业制造,深度学习通过模拟人脑神经网络的层次化学习机制,实现了对复杂数据的高效分析与决策。本…...
Docker和DockerCompose基础教程及安装教程
Docker的应用场景 Web 应用的自动化打包和发布。自动化测试和持续集成、发布。在服务型环境中部署和调整数据库或其他的后台应用。从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。 CentOS Docker 安装 使用官方安装脚本自动安装 安装命令…...
ArcGIS操作:13 生成最小外接矩阵
应用情景:筛选出屋面是否能放下12*60m的长方形,作为起降场候选点(一个不规则的形状内,判断是否能放下指定长宽的长方形) 1、面积初步筛选 Area ≥ 720 ㎡ 面积计算见 2、打开 ArcToolbox → Data Management Tools …...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...
简约商务通用宣传年终总结12套PPT模版分享
IOS风格企业宣传PPT模版,年终工作总结PPT模版,简约精致扁平化商务通用动画PPT模版,素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...
GB/T 43887-2024 核级柔性石墨板材检测
核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标: 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...
