vue 框架提供了前端开发组件的思想,可以通过组件来组合成一个完整的页面,都是随着组件数量原来越多,组件之间难免需要相互通信,那么如何实现组件之间的通信呢?下面介绍 vue 组件通信的几种方法
父子组件通信
父组件传递 props
给子组件(数据以及改变数据的方法),子组件通过 $emit
来更新父组件的状态
父组件定义,声明状态 { name: '1024nav.com' }
以及可以改变状态的方法 update()
,通过 name 传递和 @update 把 name 属性和 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 官方文档