Vue组件通信方法案例总结
目录
- 一、父组件向子组件传值(props)
- 二、子组件向父组件传值($emit)
- 三、兄弟组件传值(EventBus)
- 1. 初始化(new Vue())
- 2. 发送事件($emit())
- 3. 接收事件($on())
- 4. 移除事件监听者
- 四、Vuex
一、父组件向子组件传值(props)
步骤:
- 在父组件中通过
v-bind
将数据传给子组件 - 在子组件中通过
props
接收父组件传递过来的数据
<div id="app"> <!-- 1.通过 v-bind 将数据传给子组件 --> <test v-bind:ss='name'></test> </div> <script> var a = new Vue({ el:'#app', data:{ name:'bing', }, components: { test:{ props: ['ss'], // 2.接收父组件传递过来的数据 template:"<p>{{ss}}</p>" } } }) </script>
props使得父子之间形成一种 单向数据流
,父元素更新的时候,子元素的状态也会随之改变。
但反之会导致你的应用的数据流向难以理解,因此在子组件中不能修改父组件中的数据。
二、子组件向父组件传值($emit)
子组件通过 $emit
事件向父组件发送消息,将自己的数据传递给父组件。
步骤:
- 在子组件上绑定一个
click
事件,触发increment
方法 - 在
increment
方法中用$emit
定义一个自定义事件increment
,同时传入this.counter
参数 - 在父组件上绑定步骤2中自定义的
increment
事件,方法名为incrementTotal
- 在父组件中调用步骤3中的
incrementTotal
方法,这时incrementTotal
方法就能接收到子组件传入的参数
<div id="app"> <p>{{ total }}</p> <button-counter v-on:increment="incrementTotal"></button-counter> <!-- 步骤3 --> </div> <script> Vue.component('button-counter', { template: '<button v-on:click="increment">{{ counter }}</button>', // 步骤1 data: function () { return { counter: '子组件的数据' } }, methods: { increment: function () { this.$emit('increment', this.counter); // 步骤2 } } }); new Vue({ el: '#app', data: { total: '父组件的数据:' }, methods: { incrementTotal: function (e) { // 步骤4 this.total = this.total + e[0] console.log(e); } } }) </script>
三、兄弟组件传值(EventBus)
如果不需要类似 Vuex 这样的库来处理组件之间的数据通信,就可以考虑Vue中的 事件总线(EventBus) 来通信。
在 Vue 中可以使用 EventBus
来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。
但也就是太方便所以若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。
这个方法是通过创建一个空的 vue 实例,当做 $emit 事件的处理中心(事件总线),通过他来触发以及监听事件,方便的实现了任意组件间的通信,包含父子,兄弟,隔代组件。具体如下:
1. 初始化(new Vue())
首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。
我们可以通过两种方式来处理。
方法一: 新创建一个 event-bus.js
文件
// event-bus.js import Vue from 'vue' export const EventBus = new Vue()
方法二: 直接在项目中的 main.js
初始化 EventBus
// main.js Vue.prototype.$EventBus = new Vue() // 注意:这种方式初始化的EventBus是一个全局的事件总线
现在我们已经创建了 EventBus
,接下来你需要做到的就是在你的组件中加载它,并且调用同一个方法,就如你在父子组件中互相传递消息一样。
2. 发送事件($emit())
假设有两个Vue页面需要通信: A 和 B 。A页面中在按钮上面绑定了点击事件,发送一则消息,想通知 B页面。
<!-- A.vue --> <template> <button @click="sendMsg()">-</button> </template> <script> import { EventBus } from "../event-bus.js"; export default { methods: { sendMsg() { EventBus.$emit("aMsg", '来自A页面的消息'); // 对外发送数据 } } }; </script>
3. 接收事件($on())
接下来,需要在 B页面中接收这则消息。
<!-- B.vue --> <template> <p>{{msg}}</p> </template> <script> import { EventBus } from "../event-bus.js"; export default { data() { return { msg: '' } }, mounted() { EventBus.$on("aMsg", (msg) => { // 接收 A 发送来的消息 this.msg = msg; }); } }; </script>
4. 移除事件监听者
前面提到过,如果使用不善,EventBus会是一种灾难,到底是什么样的“灾难”了?大家都知道vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。还要就是如果业务有反复操作的页面,EventBus在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理EventBus在项目中的关系。通常会用到,在vue页面销毁时,同时移除EventBus事件监听。
如果想移除事件的监听,可以像下面这样操作:
import { EventBus } from "../event-bus.js"; EventBus.$off('aMsg', {})
EventBus.$off('aMsg')
移除应用内所有对此某个事件的监听。
或者直接调用 EventBus.$off()
来移除所有事件频道,不需要添加任何参数 。
四、Vuex
在做中大型的单页应用的时候,例如需要多人协作开发,全局维护登录状态等,我们最好还是选择vuex来进行状态管理。
vuex详解传送门
到此这篇关于Vue组件通信方法案例总结的文章就介绍到这了,更多相关Vue组件通信方法总结内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!