重点:vue的两大特性是响应式编程和组件化。组件(Component)是 Vue 最核心的功能,但是各个组件实例的作用域是相互独立的,这表明不同组件之间的数据是无法直接相互引用的。如果想要跨组件引用数据,就需要用到组件通信了,在通信之前先要理解组件之间的关系:

如上图所示:
父子关系:A与B,A与C,B与D,C与E
兄弟关系:B与C
隔代关系(可能隔更多代):A与D,A与E
跨级关系:B与E,D与E等
通信方式
一、/
父组件通过绑定一个自定义的属性,子组件通过接收父组件传来的数据;子组件通过触发事件,父组件用或者在子组件的自定义标签上使用来监听子组件触发的自定义事件,从而接收子组件传来的数据。(学习视频分享:vue视频教程)

1、父组件向子组件传值
下面通过一个例子来说明父组件向子组件传值,父组件parent.vue把数据传给子组件child.vue,并在child.vue中展示出来
// 父组件parent.vue

<template><div><Child :books="books"/></div>
</template>
<script>
import Child from './components/Child.vue'
export default {name: 'parent',components: {Child},data() {return {books: ['JavaScript高级程序设计', 'CSS新世界', '图解 HTTP 彩色版']}}
}
</script>`
// 子组件child.vue
<template><div><ul><li v-for="(item, index) in books" :key="index">{{item}}</li></ul></div>
</template>
<script>
export default {props: {books: {type: Array,default: () => {return []}}}
}
</script>

注意:通过props传递数据是单向的,父组件数据变化时会传递给子组件,但子组件不能通过修改props传过来的数据来修改父组件的相应状态,即所谓的单向数据流。
2、子组件向父组件传值
下面通过子组件点击书籍列表,用$emit()触发,然后再父组件中获取

// 子组件child.vue
<template><div><ul><li v-for="(item, index) in books" :key="index" @click="like(item)">{{item}}</li></ul></div>
</template>
<script>
export default {props: {books: {type: Array,default: () => {return []}}},methods: {like(item) {this.$emit('likeBook', item)}}
}
</script>
// 父组件parent.vue
<template><div><Child :books="books" @likeBook="likeBook"/></div>
</template>
<script>
import Child from './components/Child.vue'
export default {name: 'parent',components: {Child},data() {return {books: ['JavaScript高级程序设计', 'CSS新世界', '图解 HTTP 彩色版']}},methods: {likeBook(val) {alert('我最喜欢的书籍是《' + val + '》')}}
}
</script>

二、$parent/$children
$parent:访问父组件实例
$children:访问子组件实例

// 父组件parent.vue
<template><div><Child /><button @click="getChildData">获取子组件数据</button></div>
</template>
<script>
import Child from './components/Child.vue'
export default {name: 'parent',components: {Child},data() {return {books: ['JavaScript高级程序设计', 'CSS新世界', '图解 HTTP 彩色版']}},methods: {getChildData() {alert(this.$children[0].msg)}}
}
</script>
// 子组件child.vue
<template><div><ul><li v-for="(item, index) in bookLists" :key="index">{{item}}</li></ul></div>
</template>
<script>
export default {name: 'child',data() {return {bookLists: [],msg: '我是子组件的值!'}},mounted() {this.bookLists = this.$parent.books}
}
</script>

注意:$parent拿到的是对象,如果是最顶层没有父组件的情况下拿到的是undefined;$children拿到的是数组,如果是做底层没有子组件的情况下,拿到的是空数组;这两种通信方式只能用于父子组件通信
三、ref
ref如果在普通Dom元素上使用,引用指向的就是 DOM 元素;如果在子组件上使用,引用就指向组件实例,可以通过实例直接调用组件的方法和数据

// 父组件parent.vue
<template><div><Child ref="child" /><button @click="getChildData">获取子组件数据</button></div>
</template>
<script>
import Child from './components/Child.vue'
export default {name: 'parent',components: {Child},methods: {getChildData() {const msg = this.$refs['child'].msgconsole.log(msg)this.$refs['child'].say()}}
}
</script>
// 子组件child.vue
<script>
export default {name: 'child',data() {return {msg: '我是子组件的值!'}},methods: {say() {alert('你好,我是子组件!')}},
}
</script>

四、provide/inject
祖先组件通过provide来提供变量,子孙组件通过inject注入变量来获取祖先组件的数据,不管子孙组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据。下面是具体代码:

// 父组件
<template><div><h1>康熙</h1><Son /></div>
</template>
<script>
import Son from './components/Son.vue'
export default {components: {Son},provide() {return {FatherToSon: this.FatherToSon,FatherToGrandson: this.FatherToGrandson,}},data() {return {FatherToSon: '我是康熙,雍正,你是我儿子!',FatherToGrandson: '我是康熙,乾隆,你是我孙子!',}}
}
</script>
// 子组件
<template><div><h1>雍正</h1><button @click="receive">接收</button><Grandson /></div>
</template>
<script>
import Grandson from './Grandson.vue'
export default {components: { Grandson },inject: ['FatherToSon'],methods: {receive() {alert(this.FatherToSon)}}
}
</script>
// 孙组件
<template><div><h1>乾隆</h1><button @click="receive">接收</button></div>
</template>
<script>
export default {inject: ['FatherToGrandson'],methods: {receive() {alert(this.FatherToGrandson)}}
}</script>

注意:provide/inject只能从上往下传值,且不是响应式,若要变成响应式的数据provide需要提供函数
五、eventBus的$emit/$on
eventBus是消息传递的一种方式,基于一个消息中心,订阅和发布消息的模式,称为发布订阅者模式。
eventBus 又称为事件总线。在 Vue 中可使用 eventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。

$emit(‘name’,args): name:发布的消息名称 , args:发布的消息
KaTeX parse error: Expected 'EOF', got '&' at position 40: …息名称, fn: 订阅的消息 &̲dollar;once('na…on相似但是只触发一次,一旦触发之后,监听器就会被移除
$off(‘name’,callback):name:事件名称,callback:回调监听器
eventbus可以实现任何组件之前的通信,下面以兄弟组件为例

1、初始化,全局引入

// main.js
// 全局添加事件总线
Vue.prototype.$bus = new Vue()

2、发送事件
在parent.vue引入ChildA和ChildB组件,使它们成为兄弟组件

// 父组件parent.vue
<template><div><ChildA /><ChildB /></div>
</template>
<script>
import ChildA from './components/childA'
import ChildB from './components/childB'
export default {components: {ChildA,ChildB}
}
</script>

在ChildA组件中用$emit发送事件

// ChildA组件
<template><div><h1>组件A</h1><button @click="send">发送</button></div>
</template>
<script>
export default {methods: {// 发送事件send() {this.$bus.$emit('message', '欢迎使用eventBus!')}}
}
</script>

3、接收事件发送的事件

// ChildB组件
<template><div><h1>组件B</h1></div>
</template>
<script>
export default {mounted() {// 接收事件this.$bus.$on('message', data => {alert('我是组件B,我收到的消息为:' + data)})},beforeDestroy() {this.$bus.$off('message')}
}
</script>

注意:$on监听的事件不会自动移除监听,因此在不用时最好使用$off移除监听以免产生问题



vue各组件之间多种通信方式相关推荐

  1. VUE中组件之间的通信方式

    目录 一.父子组件之间的通信方式 1.props+$emit() 3.$parent+$children 4.provide+inject 5.$attrs+$listeners 6.ref+$ref ...

  2. Vue中组件之间8中通信方式

    vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式, 就 ...

  3. vue.js 组件之间传递数据 1

    vue.js 组件之间传递数据 框架 浏览数:437 2017-8-21 组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.如何传递数据 ...

  4. vue兄弟组件之间的传值,bus运用,beforeDestroy销毁,Bus.$off

    vue兄弟组件之间的传值 1.建立一个单独的文件bus.js import Vue from 'vue' export default new Vue() 2.传递事件 // 传递事件 import ...

  5. vue中组件之间调用方法——子组件调用父组件的方法 父组件调用子组件的方法

    vue中组件之间调用方法--子组件调用父组件的方法 & 父组件调用子组件的方法 1.vue中子组件调用父组件的方法 1.1.第一种方法是直接在子组件中通过this.$parent.event来 ...

  6. VUE父子组件之间的传值,以及兄弟组件之间的传值;

    一.Vue父子 组件之间传值 vue使用中,经常会用到组件,好处是: 1.如果有一个功能很多地方都会用到,写成一个组件就不用重复写这个功能了: 2.页面内容会简洁一些:方便管控: 子组件的传值是通过p ...

  7. vue父子组件之间传值的方法

    vue父子组件之间传值的方法 一.基本父子传值 父传子 方式: props 效果: 把父组件的fatherName属性传入子组件,在子组件中使用 父组件代码: <template>< ...

  8. VUE父子组件之间通信方式

    前言: 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使用,遇到业务逻辑操 ...

  9. vue中组件之间传值的六种方式(完整版)

    前言   组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.一般来说,组件可以有以下几种关系: 如上图所示,A 和 B.B 和 C.B ...

最新文章

  1. C++__堆,栈与内存管理
  2. CVPR‘22 最新106篇论文分方向整理|包含目标检测、动作识别、图像处理等32个方向
  3. Python使用matplotlib画图,设置曲线颜色、类型及标记
  4. 澳大利亚量子计算机获突破 首次实现简化逻辑门
  5. 从职场新人到企业高管,她是怎么做到的?
  6. java游戏西门大官人_valueOf()方法的使用
  7. linux用call调存储过程,存储过程调用其他模式的存储过程需要注意的地方
  8. 为SQL Server Always On可用性组配置故障转移群集,存储控制器和仲裁配置
  9. AQS-sync同步队列 [自定义同步器框架]
  10. 实现Eureka注册发现的高可用
  11. C++游戏开发入门制作:经典游戏拳皇97
  12. 蓝牙技术|AirPods Pro 2 支持蓝牙 LE Audio 技术带来的 5 大好处
  13. WIN10直接运行自定义软件
  14. 转载 :make报错:/usr/bin/ld: cannot find -lXXX
  15. STM32 AT24C64 Hal库写入错误
  16. 计算机专业英语职高 试卷,2020年河南高职单招英语样卷及答案分享
  17. Python wxPython基本教程
  18. 三极管计数系统的设计与实现matlab,运动控制系统课程设计-双闭环直流电动机调速系统设计及MATLAB仿真汇.docx...
  19. 利用CSS改变图片颜色的多种方法!
  20. C++ QT开发人机象棋(剪枝算法)

热门文章

  1. STM32 OLED屏(I2C接口)显示
  2. linux防网络攻击,让Linux系统有效防御ARP攻击
  3. 将带有“,”字符串分割成数组
  4. IC-14W网络IC卡读写器_银河麒麟桌面操作系统V10适配测试报告
  5. The command “” exited with code 9009
  6. 金蝶K3 WISE V14.3 完整安装包(安装盘+资源盘)共两个压缩文件# 链接:https://pan.baidu.com/s/1lxGCud58s8DGKpbSrTZ-Qw 提取码:hksc
  7. java urldecode法_java URLEncoder.decode方法解码
  8. RuntimeException异常处理汇总
  9. 由玫琳凯赞助的NFTE世界创新系列赛挑战赛公布致力于解决全球问题的青年获胜者
  10. Python threading中event的使用