在vue中,组件A如何调用组件B的方法

server/2024/10/19 15:44:15/

刚刚测试人员向我反馈,说这条提交记录审核之后,另一个页签的列表显示没有做状态的同步渲染。
我心想:竟还有这种荒唐事?

好了,废话不多说,直接上菜。这种问题,一眼前端问题(我从前端干到后端,从前台干到后厨 www),大概率就是提交审核接口并完成之后,没有同步去做数据的加载操作了。既然定位到问题所在了,那么解决的思路就很清晰了。

由于我两个页面分别在两个 vue 组件下,称之为组件 A 和组件 B 吧。也就是说,我在组件 A 提交审核之后,没有去再加载一次组件 B 的 loadList 方法,导致列表数据没有重新渲染。在 Vue 中呢,通常有几种方式可以在在一个组件(组件A)中调用另一个组件(组件B)的方法(如loadList),具体取决于组件A和组件B的关系。以下是几种常见的方式:

1、父子组件关系


如果组件A和组件B是父子关系(即组件A是父组件,组件B是子组件),可以通过以下方式调用子组件的方法。

1.1、使用 $refs

可以在父组件中使用ref来引l用子组件实例,然后调用子组件的方法。

<!-- ComponentA.vue -->
<template><div><ChildComponent ref="childRef" /><button @click="callChildMethod">Call Child Method</button></div>
</template><script>javascript">
import ChildComponent from './ChildComponent.vue';export 	default {components: {ChildComponent},methods: {callChildMethod() {this.$refs.childRef.loadList();}}
}
</script>
<!-- ComponentB.vue -->
<template><div><!-- Child Component Content --></div>
</template><script>javascript">
export default {methods: {loadList() {console.log('loadList method called');// Your logic here}}
}
</script>

1.2、通过事件总线或 $emit

如果你希望从父组件触发子组件的方法,你也可以通过事件传递。子组件监听一个事件,父组件触发该事件。

<!-- ComponentA.vue -->
<template><div><ChildComponent @triggerLoad="callLoadList" /><button @click="emitLoadEvent">Call Child Method via Event</button></div>
</template><script>javascript">
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {emitLoadEvent() {this.$emit('triggerLoad');}}
}
</script>
<!-- ComponentB.vue -->
<template><div><!-- Child Component Content --></div>
</template><script>javascript">
export default {methods: {loadList() {console.log('loadList method called');// Your logic here}},mounted() {this.$on('triggerLoad', this.loadList);}
}
</script>

2、兄弟组件关系


如果组件A和组件B是兄弟组件(即它们都有同一个父组件),你可以通过事件总线或者通过父组件调用的方式来实现。

2.1、使用父组件调用兄弟组件的方法

父组件作为中介来调用一个兄弟组件的方法。

<!-- ParentComponent.vue -->
<template><div><SiblingA @callSiblingB="callSiblingBMethod" /><SiblingB ref="siblingBRef" /></div>
</template><script>javascript">
import SiblingA from './SiblingA.vue';
import SiblingB from './SiblingB.vue';export default {components: {SiblingA,SiblingB},methods: {callSiblingBMethod() {this.$refs.siblingBRef.loadList();}}
}
</script>
<!-- SiblingA.vue -->
<template><div><button @click="$emit('callSiblingB')">Call Sibling B Method</button></div>
</template><script>javascript">
export default {
}
</script>
<!-- SiblingB.vue -->
<template><div><!-- Sibling B Content --></div>
</template><script>javascript">
export default {methods: {loadList() {console.log('loadList method called');// Your logic here}}
}
</script>

3、使用事件总线


创建一个全局的事件总线,然后在组件A中发出事件,在组件B中监听事件并调用方法。

javascript">// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
<!-- ComponentA.vue -->
<template><div><button @click="triggerLoad">Call B's loadList</button></div>
</template><script>javascript">
import { EventBus } from './eventBus';export default {methods: {triggerLoad() {EventBus.$emit('loadList');}}
}
</script>
<!-- ComponentB.vue -->
<template><div><!-- Component B Content --></div>
</template><script>javascript">
import { EventBus } from './eventBus';export default {methods: {loadList() {console.log('loadList method called');// Your logic here}},mounted() {EventBus.$on('loadList', this.loadList);}
}
</script>

4、我的场景


在我的项目中,组件 A 和组件 B 是存在互相调用的关系的,并且它们之间没有联系。那么可以用事件总线来解决这个问题。
如果组件 A 和组件 B 之间没有直接的父子或兄弟关系,但需要互相调用对方的方法,可以使用事件总线(EventBus)来实现它们之间的通信。这种方式允许在不直接引l用对方的情况下,在组件 A 中调用组件 B 的方法,反之亦然。

  1. 创建一个全新的事件总线
    首先,创建一个全局的事件总线。这个事件总线可以在多个组件之间传递事件。
    // eventBus.js
    import Vue from ‘vue’;
    export const EventBus = new Vue();

  2. 组件 A 监听组件 B 的事件,并调用组件 B 的方法
    在组件A中,当需要调用组件B的方法时,可以通过事件总线发送事件。

<!-- ComponentA.vue -->
<template><div><button @click="callBMethod">Call B's loadList</button></div>
</template><script>javascript">
import { EventBus } from './eventBus';export default {methods: {loadList() {// ...},callBMethod() {// 发送事件通知B去调用B的loadList方法EventBus.$emit('loadList')}},mounted() {// 监听B发送的事件EventBus.$on('loadList', this.loadList);},
}
</script>
  1. 组件 B 监听 A 组件的事件,并调用组件 A 的方法
    在组件B中,监听由事件总线发出的事件,当接收到事件时调用自己的方法。
<!-- ComponentB.vue -->
<template><div><!-- Component B Content --></div>
</template><script>javascript">
import { EventBus } from './eventBus';export default {methods: {loadList() {// ...},callAMethod() {// 发送事件通知A去调用A的loadList方法EventBus.$emit('loadList')}},mounted() {// 监听A发送的事件EventBus.$on('loadList', this.loadList);},beforeDestroy() {// 清理事件监听器EventBus.$off('loadList', this.loadList);}
}
</script>

通过使用事件总线,组件A和组件B可以在没有直接关系的情况下进行互相调用。这种方式非常适合在组件之间需要进行复杂通信但没有直接层级关系时使用。在大型项目中,也可以使用更为复杂的状态管理工具如Vuex来处理这种需求。

可以看到,组件 A 和组件 B 都在各自的 mounted 钩子中监听了 loadList 事件,对于 vue 来说,其实它无法区分调用的是哪个组件下的 loadList,那么 EventBus.$emit('loadList')将会触发 A 组件和 B 组件中的 loadList方法。这是因为事件总线(EventBus)是全局的,这意味着通过 EventBus 发送的事件会被任何监听该事件的组件接收。当你在A组件中调用 EventBus.$emit('loadList')时,任何正在监听loadList 事件的组件都会执行与该事件相关联的方法。

对于这种方法同名的情况,可以采用以下几种方式来区分:

  1. 使用不同的事件名称
    给不同的组件使用不同的事件名称,例如 loadListA 和 loadListB。
    // A组件中监听
    EventBus.$on('loadListA', this.loadList);

// B组件中监听
EventBus.$on('loadListB', this.loadList);
// 在A组件中触发事件
EventBus.$emit('loadListA');

// 在B组件中触发事件
EventBus.$emit('loadListB');

  1. 使用参数区分
    可以通过给 loadList 事件传递一个参数,来区分是哪个组件需要触发该事件。
javascript">// A组件中监听
EventBus.$on('loadList', (source) => {if (source === 'A') {this.loadList();}
});// B组件中监听
EventBus.$on('loadList', (source) => {if (source === 'B') {this.loadList();}
});
// 在A组件中触发事件,传递参数 'A'
EventBus.$emit('loadList', 'A');// 在B组件中触发事件,传递参数 'B'
EventBus.$emit('loadList', 'B');
  1. 在 beforeDestroy 中解除监听
    如果你只希望某个组件在特定时间段内监听事件,可以在组件销毁前解除监听。
javascript">// A组件中监听
EventBus.$on('loadListA', this.loadList);beforeDestroy() {EventBus.$off('loadListA', this.loadList);
}

http://www.ppmy.cn/server/111424.html

相关文章

百度:未来or现在 顾此失彼?

用AI押注未来&#xff0c;却丢了现在 国内AI先行者百度 走到哪了&#xff1f; 作为这个星球最热门的概念&#xff0c;AI无疑是个好故事&#xff0c;不只是百度&#xff0c;美股的一众科技公司几乎都在讲述自己的AI投入及发展成果&#xff0c;市值也随着AI预期坐过山车。而市场…

架构基础 -- Web框架之FastAPI

FastAPI&#xff1a;背景与使用案例介绍 FastAPI的背景 FastAPI是一个现代、快速&#xff08;高性能&#xff09;的Web框架&#xff0c;基于Python 3.7编写&#xff0c;利用Python的类型提示&#xff08;type hints&#xff09;来实现自动生成文档和高效的数据验证。由Sebast…

Nginx: https解决安全问题

https原理 1 &#xff09;http协议存在的问题 数据使用明文传输&#xff0c;可能被黑客窃取 (需要信息加密)报文的完整性无法验证&#xff0c;可能被黑客篡改 (需要完整性校验)无法验证通信双方的身份&#xff0c;可能被黑客伪装 (需要身份认证) 2 ) https 原理 所谓 https,…

selenium无法定位元素的几种解决方案

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、frame/iframe表单嵌套 WebDriver只能在一个页面上对元素识别与定位&#xff0c;对于frame/iframe表单内嵌的页面元素无法直接定位。 解决方法&#xff1a; d…

用于全栈自动化测试的最佳Python工具

我知道大多数测试人员会说Java是他们创建自动化测试的首选语言。 但是我最喜欢的是Python。为什么?为什么是Python ? Al Sweigart&#xff0c;《自动化那些无聊的东西》的作者&#xff0c;Python一直是他的首选语言&#xff0c;因为:它有一个温和的学习曲线。它适用于Windows…

数据结构-广义表

目录 一、逻辑结构 二、存储结构 一、逻辑结构 ①A()&#xff0c;A是一个空表&#xff0c;长度为0&#xff0c;深度为1 ②B(d,e)&#xff0c;B的元素全是原子(d,e)&#xff0c;长度为2&#xff0c;深度为1 ③C(b,(c,d))&#xff0c;C有两个元素&#xff0c;分别是原子b和广…

百度飞将 paddle ,实现贝叶斯神经网络 bayesue neure network bnn,aistudio公开项目 复现效果不好

论文复现赛&#xff1a;贝叶斯神经网络 - 飞桨AI Studio星河社区 https://github.com/hrdwsong/BayesianCNN-Paddle 论文复现&#xff1a;Weight Uncertainty in Neural Networks 本项目复现时遇到一个比较大的问题&#xff0c;用pytorch顺利跑通源代码后&#xff0c;修改至pad…

对同一文件夹下所有excel表进行相同操作(数据填充、删除、合并)

背景引入&#xff1a;如图所示&#xff0c;笔者需要对数十个表格的银行日记账工作簿合并成一个工作簿&#xff0c;以便与本月银行流水进行核对。 为了方便银行日记账与银行流水进行核对&#xff0c;需要再每个村或小组的表格中&#xff0c;将村或小组的名称放在J列。 clear c…