跳到主内容

vue组件之间如何通信,有多少种方式?

· 4分钟阅读

vue 框架提供了前端开发组件的思想,可以通过组件来组合成一个完整的页面,都是随着组件数量原来越多,组件之间难免需要相互通信,那么如何实现组件之间的通信呢?下面介绍 vue 组件通信的几种方法

父子组件通信

父组件传递 props 给子组件(数据以及改变数据的方法),子组件通过 $emit 来更新父组件的状态

父组件定义,声明状态 { name: '1024nav.com' } 以及可以改变状态的方法 update(),通过 name 传递和 @updatename 属性和 update 方法传递给子组件

父子组件通信

<template>
<div id="app">
<Child :name="name" @update="update" />
</div>
</template>

<script>
import Child from "./components/Child";

export default {
name: "App",
components: {
Child,
},
data() {
return {
name: "1024nav.com",
};
},
methods: {
update() {
this.name = "www.1024nav.com";
},
},
};
</script>

子组件的定义,定义 props 接收 name 属性,通过 $emit 传递 update 参数通知父组件更新状态

<template>
<div className="hello">
{{ name }}
<button @click="$emit('update')">通知父组件数据</button>
</div>
</template>

<script>
export default {
name: "Child",
props: {
name: String,
},
};
</script>

父组件与子孙组件的通信

父组件通过 provide 创建对象,子组件通过 inject 来使用父组件的数据,不受组件层级的限制

父组件通过 provide 定义需要传递是数据

<template>
<div id="app">
<Child />
</div>
</template>

<script>
import Child from "./components/Child";

export default {
name: "App",
components: {
Child,
},
provide: {
name: "www.1024nav.com",
},
};
</script>

子组件通过 inject 属性控制哪些属性需要访问

<template>
<div className="hello">{{ name }}</div>
</template>

<script>
export default {
name: "Child",
inject: ["name"],
};
</script>

父组件获取子组件数据

通过 ref 来获取子组件的实例,可以获取子组件的状态或者调用子组件的方法,例如下面

<template>
<div id="app">
<Child ref="child" />
</div>
</template>

<script>
import Child from "./components/Child";

export default {
name: "App",
components: {
Child,
},
mounted() {
console.log(this.$refs.child.title);
},
};
</script>

可以通过 this.$refs.child 获取到 Child 组件的实例,访问 Child 组件的 data

无需考虑组件关系的通信

  • 通过 vue 提供的发布订阅模式,也叫做 EventBus(事件总线)

定义一个 eventBus 实例

import Vue from "vue";
export default new Vue();

父组件在 mounted 生命周期里面通过 $on 监听 update 事件

<template>
<div id="app">
<Child :name="name" />
</div>
</template>

<script>
import Child from "./components/Child";
import eBus from "../eventBus";

export default {
name: "App",
data() {
return {
name: "1024nav.com",
};
},
components: {
Child,
},
mounted() {
eBus.$on("update", (val) => {
// 监听后改变数据
this.name = val;
});
},
};
</script>

子组件通过 vue 实例的 $emit 触发 update 事件

<template>
<div className="hello">
{{ name }}
<button @click="clickHandle">通知父组件更新</button>
</div>
</template>

<script>
import eBus from "../../eventBus";

export default {
name: "Child",
props: {
name: String,
},
data() {
return {
title: "child component",
};
},
methods: {
clickHandle() {
// 通知订阅者,传递参数
eBus.$emit("update", "Hello World");
},
},
};
</script>
  • 使用全局状态管理库 vuex

具体就不在这里展开讲,有兴趣的可以查阅 vue 官方文档