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 …...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...