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. .Net Core Serverless初体验

    什么是Serverless Serverless 是一个当今软件世界中比较新的话题.它并没有一个普遍公认的权威定义,每个人每个企业对它的解释可能都有不同,而 Serverless 正是在这种情况下不断 ...

  2. e课表项目第二次冲刺周期第二天

    昨天干了什么? 昨天与我们小组的成员商量了一个重大的决定,确定了我们转型发展的主题,简要的设计了我们软件要实现的功能,并且完成了首导航栏的设计,和一部分框架的内容填充. 今天干了什么? 我们组今天通过 ...

  3. java架构之路-(Redis专题)Redis的高性能和持久化

    上次我们简单的说了一下我们的redis的安装和使用,这次我们来说说redis为什么那么快和持久化数据 在我们现有的redis中(5.0.*之前的版本),Redis都是单线程的,那么单线程的Redis为 ...

  4. Flask中的CBV以及正则表达式

    Flask中的CBV以及正则表达式 一.CBV def auth(func): def inner(*args, **kwargs): print('before') result = func(*a ...

  5. eclipse常用快捷键即项目操作

    快捷键: 1.代码提示:Alt+/ 2.撤销上一步操作:Ctrl+z:取消撤销:Ctrl+y: 3.如何注销一整段代码?☞▲第一种注释方法是每行代码前加//:先选中,然后按Ctrl+/:取消注销方法一 ...

  6. ssh隧道代理连接

    0x00 什么是SSH隧道 场景: 假设有两台主机: A主机为外网,B主机为内网通常来说外网主机A是无法直接连接到内网主机B的,这时如果要实现A主机通过ssh控制B主机,通常来说有两种方法: 1.端口 ...

  7. PHP get_class_vars 和 (array)

    <?php class Girl { public $id = 1; public $name = 'zhy'; } $start = microtime(TRUE); var_dump(get ...

  8. [LUOGU2964] [USACO09NOV]硬币的游戏A Coin Game

    题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game c ...

  9. Linux::mysql-connector-c++

    .安装好boost. .从官网下载mysql connector c++版本. .解压,复制 include/jdbc/cppconn 文件夹复制,到/usr/local/include/cppcon ...

  10. Flink 从 0 到 1 学习 —— 如何自定义 Data Source ?

    前言 在 <从0到1学习Flink>-- Data Source 介绍 文章中,我给大家介绍了 Flink Data Source 以及简短的介绍了一下自定义 Data Source,这篇 ...