vue 组件通信总结
场景
- 子组件调用父组件方法
- 子组件调用祖先组件方法
- 父组件调用子组件方法
- 拥有同一个祖先的组件之间互相调用
自定义事件
通过自定义事件,可以在子组件内调用父组件的方法.
父组件
<div>
<my-child @customer-event="console.log('customer-event triggered')"></my-child>
</div>
子组件
<button @click="$emit('customer-event')">
provide / inject
父组件通过provide
提供 callable 对象,后代组件通过inject
接收后就可以进行调用.
使用这种方法子组件不仅仅可以调用父组件方法,因为对方法的查找是逐级向上的,直到找到为止.
父组件中
export default {
provide: {
foo: (x) => console.log(x),
},
};
子组件
export default {
inject: ["foo"],
};
eventbus
这种方式最为灵活,在 Vue 中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的 Vuex 作为状态管理中心,将通知的概念上升到共享状态层次。
- 定义 eventbus
import Vue from "vue";
export const EventBus = new Vue();
- 发送方组件
<template>
<button @click="sendMsg()">-</button>
</template>
<script>
import { EventBus } from "../event-bus.js";
export default {
methods: {
sendMsg() {
EventBus.$emit("aMsg", '来自发动方的消息');
}
}
};
- 接收方组件
<template>
<p>{{ msg }}</p>
</template>
<script>
import { EventBus } from "../event-bus.js";
export default {
data() {
return {
msg: "",
};
},
mounted() {
EventBus.$on("aMsg", (msg) => {
this.msg = msg;
});
},
};
</script>
$refs
使用$refs
可以在父组件中拿到子组件实例,进而调用其方法.
父组件
<template>
<div>
<my-child $ref="my-child"></my-child>
</div>
</template>
<script>
export default {
mounted() {
this.$refs.my-child.func();
},
};
</script>
子组件
<template>
<div></div>
</template>
<script>
export default {
name: "my-child",
methods: {
func: function () {},
},
};
</script>