1.前言

Vue框架倡导组件化开发,力求将一个大的项目拆分成若干个小的组件,就如同我们小时玩堆积木一样,一个大房子是由若干个小积木组成。组件化开发最大问题就是组件之间数据能够流通,即组件之间能够通信。而组件间通信无非就分为三种情况:外层的大组件向内部的小组件通信,内部的小组件向外部的大组件通信,平级之间组件通信。说的官方一点就是:

  • 父组件与子组件通信
  • 子组件与父组件通信
  • 非父子组件通信

针对这三种情况,下面将一一展开介绍。

2.父组件 — —> 子组件

父组件向子组件传递数据通过props。通俗的讲就是:父组件在调用子组件时,在子组件标签内传入形如key=value属性,而子组件内部用props去接住父组件传来的key,进而再拿到传来的value值。

举个栗子:

我们现在有这样一个需求:

在某个项目中,包含了若干个顶部标题栏,而每个顶部标题栏的标题都各不一样,我们希望能够实现一个通用的标题栏组件,使得在之后需要标题栏的地方直接调用这个组件,并只需在调用的时候传入所要显示的标题文字,来满足标题栏相同而标题各不相同的需求。

上述需求是一个经典的父组件向子组件通信(传递数据)的需求,通用的标题栏组件时子组件,父组件是调用该标题栏的父组件,父组件传入不同的标题文字,子组件来渲染父组件所需要的标题。话不多说,直接上代码:

子组件代码:

 //子组件代码
<template>
<div class="header">{{ titleText }}</div>
</template> <script>
export default {
name: "Child",
props:['title'],
data(){
return{
titleText:this.title
}
}
}
</script> <style scoped>
.header{
width: 100%;
height: 100px;
background-color: #ccc;
text-align: center;
font-size: 50px;
line-height: 100px;
}
</style>

父组件代码:

 //父组件代码
<template>
<div id="app">
<Child :title="msg"></Child>
</div>
</template> <script>
import Child from './Child'
export default {
name: 'app',
components:{
Child
},
data () {
return {
msg:'难凉热血'
}
}
}
</script> <style>
*{
margin: 0;
padding: 0;
}
</style>

从上面代码中,我们可以看到,父组件在调用子组件时,向子组件传递了一个名为title的属性,同时该title属性对应了父组件自己内部的一个值msg,传递过去后,子组件通过自己本身的props选项中的title来接住父组件传过来的值,接着再将拿到的数据应用到自己需要的地方。这样,就完成了父组件向子组件通信的过程。

我们也就完成了上面提出的需求,我们只需在需要标题栏的地方调用该组件并且在调用的时候传入我们想要的title值即可。

3.子组件 — —> 父组件

子组件向父组件传递数据需要借助内建的 $emit 方法通过事件的方式来传递。

$emit方法是vue实例的一个方法,该方法就像一个广播,亦或者像一个信号发射器,该方法接受两个参数:

 vm.$emit('信号名字',‘信号数据’)
  • 第一个参数:信号名字。即我要发射的这个信号的名字,我有可能发射多个信号,信号名字用于区分各个信号
  • 第二个参数:信号数据。即发射出的真实的信号内容,也就是数据。

再举个栗子:

想象这么一个情景:我军准备发动一次军事行动,行动代号:“打狗”。行动内容:“攻打美国白宫,实现全球统一!!!”那么由中央军委发射信号,军队接收信号。代码如下:

中央军委发射信号:

 中央军委.$emit('打狗','攻打美国白宫,实现全球统一!!!')

军队接收信号:

 军队.$on('打狗',function(data){
//data就是接收到的信号内容:攻打美国白宫,实现全球统一!!!
console.log(data)
})

OK,了解了上述过程,我们就可以实现子组件向父组件通信,由子组件发射信号,父组件接收信号。

子组件代码如下:

 //子组件代码
<template>
<div class="header">
<p>我是子组件,我要向父组件传递的数据是:{{msg}}</p>
<button @click="emit">发射</button>
</div>
</template> <script>
export default {
name: "Child2",
data(){
return{
msg: "攻打美国白宫,实现全球统一!!!"
}
},
methods:{
emit(){
this.$emit('dagou',this.msg)
}
}
}
</script> <style scoped>
.header{
width: 100%;
height: 100px;
background-color: #ccc;
text-align: center;
}
</style>

父组件代码:

 //父组件代码
<template>
<div id="app">
<Child @dagou="go"></Child>
<p>我是父组件,我接收到子组件传递的数据是:{{msg}}</p>
</div>
</template> <script>
import Child from './Child2'
export default {
name: 'app',
components:{
Child
},
data () {
return {
msg:''
}
},
methods:{
go(data){
this.msg = data
}
} }
</script> <style>
*{
margin: 0;
padding: 0;
}
</style>

效果如图:

从上面代码中,我们可以看到,子组件点击发射按钮之后,广播了一个名为dagou的信号,同时发出了信号数据:“攻打美国白宫,实现全球统一!!!”(子组件第19行代码),与此同时,父组件监听@dagou信号(父组件第4行代码),当监听到dagou信号后,调用自身的go函数,同时go函数接受到了传来的数据,这样,就完成了子组件向父组件通信的过程。

4.非父子组件通信

所谓非父子组件,指的是这两个组件没有任何关系,有可能这两个组件各自存在于不同于的父组件内,那么,这种情况下两个组件又该如何通信呢?

在通常情况下,两个非父子组件要进行简单的通信,我们会一般采用中央事件总线的机制,说白了,就是找一个中间传话人,A组件要与B组件说话,那A组件就先给中间传话人说,然后由中间传话人告诉B组件。

那么,在代码中,我们会实例化一个空的vue实例组件用来充当这个中间传话人,请看如下代码:

用于中间传话的空vue组件代码:

 //eventBus空组件,什么也不写,只用于传话
<template> </template> <script>
import Vue from 'vue'
export default new Vue();
</script> <style scoped> </style>

A组件代码:

 //A组件代码
<template>
<div>
<p>我是A组件,我要给B组件说:{{toBmsg}}</p>
<button @click="say">对B说</button>
</div>
</template> <script>
import eventBus from './eventBus'
export default {
name: "A",
data(){
return{
toBmsg:"hello,我是A组件"
}
},
methods:{
say(){
eventBus.$emit('haha',this.toBmsg)
}
}
}
</script> <style scoped> </style>

B组件代码:

 //B组件代码
<template>
<p>我是B组件,我听到A组件给我说:{{msgText}}</p>
</template> <script>
import eventBus from './eventBus'
export default {
name: "B",
data(){
return{
msgText:''
}
},
created(){
let self = this;
eventBus.$on('haha',function (data) {
//此处没有用this,是因为此处的this指向了eventBus
self.msgText = data
})
}
}
</script> <style scoped> </style>

效果如图:

至此,三种情况下的组件间通信的方式介绍完毕。

(完)

通俗易懂了解Vue组件的通信方式的更多相关文章

  1. Vue 组件的通信方式都有哪些?

    说一下 Vue 组件的通信方式都有哪些?(父子组件,兄弟组件,多级嵌套组件等等) 一.父组件向子组件传值 二.子组件向父组件传值 三.兄弟组件传值 四.跨组件 一.父组件向子组件传值 1.1props ...

  2. Vue组件间通信方式到底有几种

    1. 前言 Vue的一个核心思想就是组件化.所谓组件化,就是把页面拆分成多个组件 (component),每个组件依赖的 CSS.JavaScript.模板.图片等资源放在一起开发和维护.组件是资源独 ...

  3. vue 组件的通信方式(完整版)

    几种通信方式无外乎以下几种: Prop(常用) $emit (组件封装用的较多) .sync语法糖 (较少) $attrs & $listeners (组件封装用的较多) provide &a ...

  4. Vue组件间通信方式

    一.Props传递数据 在父组件中使用子组件,本质通过v-bind绑定属性传入子组件,子组件通过props接收父组件传入的属性 <template> <div> 父组件:{{m ...

  5. 通俗易懂了解Vue组件的生命周期

    1.前言 在使用vue2.0进行日常开发中,我们总有这样的需求,我就想在页面刚一加载出这个表格组件时就发送请求去后台拉取数据,亦或者我想在组件加载前显示个loading图,当组件加载出来就让这个loa ...

  6. 整理4种Vue组件通信方式

    整理4种Vue组件通信方式 重点是梳理了前两个,父子组件通信和eventBus通信,我觉得Vue文档里的说明还是有一些简易,我自己第一遍是没看明白. 父子组件的通信 非父子组件的eventBus通信 ...

  7. Vue组件通信方式(一)

    组件与组件的关系,通常有父子关系,兄弟关系以及隔代关系. 针对不同的场景,如何选用适合的通信方式呢? (一) props/$emit parentComponent ==> childCompo ...

  8. Vue组件通信方式全面详解

    vue组件通信方式全面详解 众所周知,Vue主要思想就是组件化开发.因为,在实际的项目开发中,肯定会以组件的开发模式进行.形如页面和页面之间需要通信一样,Vue 组件和组件之间肯定也需要互通有无.共享 ...

  9. Vue.js组件间通信方式总结

    平时在使用Vue框架的业务开发中,组件不仅仅要把模板的内容进行复用,更重要的是组件之间要进行通信.组件之间通信分为三种:父-子:子-父:跨级组件通信.下面,就组件间如何通信做一些总结. 1.父组件到子 ...

随机推荐

  1. Springboot之初入江湖

    Hello,各位小伙伴大家好,我是小栈君. 今天的分享主题是关于Springboot主题分享,其实在写这个系列主题之前有想过一些关于分享技术的顺序问题,因为我在创建"IT干货栈"这 ...

  2. C#基于Quartz.NET实现任务调度并部署Windows服务

    一.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和asp ...

  3. mysql启动错误1067进程意外终止的解决方法

    一.环境介绍 1.mysql主从复制中的从服务器 2.Windows Server 2008 R2 Enterprise系统 64位操作系统 3.MySQL数据库版本为5.6.34 二.报错详情 从服 ...

  4. linux ln命令 建立文件夹桌面快捷方式

    指令如下: sudo ln -s /root/myhack/ /root/Desktop 以上指令是创建软链接到桌面. 指令解析: ln -s是创建软链接指令,如果不加-s则是创建硬链接.

  5. Halcon一日一练:图像分割之阈值分割1

    先了解什么是阈值,度娘告诉我的是:一个领域或一个系统的界限称为阈,其数值称为阈值.在图像中,我们把图像看成一个由像素灰度值组成的数集,那么阈,就是这个图像中,根据目标与背景灰度值的差异,选取的一个合适 ...

  6. Python编程系列---使用装饰器传参+字典实现动态路由

    # 实现一个空路由表,利用装饰器将url和功能函数的对应关系自动存到这个字典中 router_dict = {} # 定义一个装饰器 # 再给一层函数定义,用来传入一个参数,这个参数就是访问的页面地址 ...

  7. C#发送电子邮件(SMTP)及outlook.com账号之概要

    这是关于c#发送电子邮件(SMTP)的技术笔记,以”简报“形式呈现. 因为最后成功通过outlook.com发送了邮件,所以,我觉得还是有必要 记录一下其中的要点. 一.技术核心 .net Frame ...

  8. linux "No space left on device" 磁盘空间解决办法

    某年某月某日某时,某人在工作中设置crontab定时任务规则保存时,提示“No space left on device”,此时用df -h检查磁盘,发现还有剩余空间.请问是什么原因及如何排查?什么会 ...

  9. JVM学习记录2--垃圾回收算法

    首先要明确,垃圾回收管理jvm的堆内存,方法区是堆内存的一部分,所以也是. 而本地方法栈,虚拟机栈,程序计数器随着线程开始而产生,线程的结束而消亡,是不需要垃圾回收的. 1. 判断对象是否可以被回收 ...

  10. Unity C#数据持久化与xml

    最近工作需要用到数据持久化,所以在此分享一下,通过查阅资料,数据持久化大体都是通过xml或者json来进行的.unity为我们自定义了数据持久化方法,但是比较局限,还需要自己来完成数据持久化方法. ( ...