vue组件之间的传值——中央事件总线与跨组件之间的通信($attrs、$listeners)
vue组件之间的通信有很多种方式,最常用到的就是父子组件之间的传值,但是当项目工程比较大的时候,就会出现兄弟组件之间的传值,跨级组件之间的传值。不可否认,这些都可以类似父子组件一级一级的转换传递,但是当项目比较大,功能比较复杂的时候,就会变得比较冗余,代码不利于维护;这时候可能会有很多人使用到vuex,但是如果项目中多个组件共享状态比较少,项目比较小,并且全局状态比较少,好像就没有使用vuex来管理数据的必要。
一、中央事件总线(eventBus)
主要是通过在要相互通信的兄弟组件之中,都注册引入一个新的vue实例,然后通过分别调用这个实例的事件触发和监听来实现通信和参数传递,也就是我们常说的bus车事件。
1、首先,全局注册一个新的vue实例,可以放在我们常用的vue项目文件中
js/event-bus.js
import Vue from 'vue'
export default new Vue()
2、如果不想全局引用可以,在使用的vue文件里使用,举个例子:contentLeft.vue,contentRight.vue 需要将contentLeft.vue与contentRight.vue互相通信
contentLeft.vue
<template>
<div>
{{message}}
<button @click="handleClick">test</button>
</div>
</template> <script>
import bus from '../../assets/js/event-bus' export default {
data () {
return {
message: 'this is content here'
}
},
props: {
con: {
type: String
}
},
components: {
descripe
},
methods: {
handleClick () {
bus.$emit('getDate', 'brathers!')
}
}
}
</script>
contentRight.vue
<template>
<div>
{{message}}
<p v-for="(item,index) in meslist" :key="index">{{item}}</p>
</div>
</template> <script>
import bus from '../../assets/js/event-bus'
export default {
data () {
return {
message: '',
meslist: []
}
},
created () {
bus.$on('getDate', (val) => {
console.log(val)
this.message = val
// this.meslist.push(val)
})
},
beforeDestroy () {
// 组件销毁前需要解绑事件。否则会出现重复触发事件的问题!!!!!!!!!!!!!
bus.$off('getDate')
}
}
</script>
当点击contentLeft的按钮的时候,contentRight的message值就获取到了总left中传过来的'brothers'
优点:通过bus事件方法可以简单快捷的进行组件之间的传值,在项目不大的时候,减少了对vuex的依赖
缺点:1、bus事件对生命周期比较严谨,当你bus.$emit发送事件时,如果兄弟组件还不存在,当真正打开兄弟组件时,此时在created里面bus.$on是监听不到传递的值的
2、bus事件不会随着组件的关闭而自行销毁,所以当路由切换时,bus事件会不停的触发,如果数据量比较多的时候,可能会比较影响性能吧,所以需要及时销毁所绑定的bus事件
二、跨组件之间的通信
vue2.4之后,跨组件之间的通信可以通过$attr和$listeners来实现
举个例子,father.vue child.vue grandChild.vue
father.vue组件中传值
<template>
<div class="about">
<p>子组件给父组件传值,父组件再给父组件传值</p>
<child
:con="con"
:son="son"
@getCData = "getCData"
></child>
</div>
</template> <script>
import child from './components/child' export default {
data () {
return {
test: 'test',
con: 'child',
son: 'child-child'
}
},
components: {
child
},
methods: {
getGrandChildData (val) {
this.son = val
console.log('这是来自grandchild组件的数据:' + val)
console.log(this.son)
}
}
}
</script>
child.vue组件中设置grandChild组件的$attr和$listner属性
<template>
<div>
{{message}}
<i class="get-data">{{con}}</i>
<grandChild v-bind="$attrs" v-on="$listeners"></grandChild >
<button @click="handleClick">test</button>
</div>
</template> <script>
import grandChild from './grandChild ' export default {
data () {
return {
message: 'this is content here'
}
},
props: {
con: {
type: String
}
},
components: {
grandChild
}
}
</script>
grandChild.vue组件可以通过$attr监听到爷爷级组件的值,再通过触发事件向爷爷级组件传递修改值
<template>
<div>
{{list}}
<p class="get-data">{{$attrs.son}}</p>
<input type="text" v-model="$attrs.son">
<button @click="passData($attrs.son)">按一下</button>
</div>
</template> <script>
export default {
data () {
return {
list: 'ceshixia'
}
},
methods: {
passData (val) {
// 触发事件,改变值爷爷级组件的值
this.$emit('getGrandChildData', val)
}
}
}
</script>
以上就可以实现跨级组件之间的传值,可以引用到各种场景中去
vue组件之间的传值——中央事件总线与跨组件之间的通信($attrs、$listeners)的更多相关文章
- python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)
昨日内容回顾 0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue ...
- vue笔记 - 组件间通信 之 中央事件总线bus
中央事件总线 - 就是一个名字可以叫做bus的vue空实例,里边没有任何内容: var bus = new Vue(); 人如其名,她就像一个公交车一样,来回输送人,将a站点的A输送到b站点,再将b站 ...
- vue bus 中央事件总线
1.全局定义bus 新建src/eventBus.js 文件 import Vue from 'vue' export default new Vue() // 全局引入mai.jsvue中央事件总 ...
- Vue开发中的中央事件总线
在Vue开发中会遇到大量的组件之间共享数据的情形,针对不同的情形,Vue有相对应的解决方案.比如,父组件向子组件传值可以使用props,复杂项目中不同模块之间传值可以使用Vuex.但是,对于一些简单的 ...
- 记一笔vue中的中央事件总线的问题,以及解决方案
代码结构:首先HeaderNav组件是被单独拎出来的,router-view中就对应了内容组件,由于有时候i有的界面的header内容是不一样的,因此要用到兄弟组件的相互通信,这个时候我首先选择了bu ...
- vue 非父子组件之间的传值(Bus/总线/发布订阅模式/观察者模式)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- vue中央事件总线eventBus的简单理解和使用
公共事件总线eventBus的实质就是创建一个vue实例,通过一个空的vue实例作为桥梁实现vue组件间的通信.它是实现非父子组件通信的一种解决方案. 用法如下: 第一步:项目中创建一个js文件(我通 ...
- 中央事件总线 事件驱动架构(EDA) 解析事件总线的4种实现方式
事件驱动架构(EDA)https://mp.weixin.qq.com/s/nA8XFD2Rx_7qA_LxltGGHw https://mp.weixin.qq.com/s/cD3auglgKzOb ...
- RRiBbit,一个事件总线.基于spring配置不同服务通信!
1.何为RRiBbit? *一种开源事件总线技术,能够让模块(组件)之间双向通讯,也被称为请求相应总线(request-response-bus),使用简单,相对其他框架来说,RRiBbit只需要加个 ...
随机推荐
- WPF Textblock Run 空白问题
消除Run之前的空白是将Run标签布局时头尾相连 如: <TextBlock > <Run Text="A"></Run> <Run Te ...
- WPF 特殊符号 字符绑定
<Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=" ...
- /etc/passwd和/etc/group文件详解
用户管理 想要知道, 系统中有哪些用户, 可以查看这个文件: /etc/passwd root:x:::root:/root:/bin/bash bin:x:::bin:/bin:/sbin/nolo ...
- 虚拟机安装 ubuntu 后,更新源无效,以及无法联网安装软件的问题
问题: 虚拟机安装 ubuntu 后,更新源无效,以及无法联网安装软件: 错误提示: Err http://security.ubuntu.com/ubuntu/ trusty-security/un ...
- Tensorflow 又要升级了。Nvidia驱动升级,牵一发而动全身
如题. 以前好好的,在宿主主机上,升级了下Linux的内核到4.15.0-13 Ubuntu16.04 以前的nvidia 驱动竟然也调了.用tensorflow 的GPU加速,必须使用nvidia ...
- 【Flink】Flink 底层RPC框架分析
1. 前言 对于Flink中各个组件(JobMaster.TaskManager.Dispatcher等),其底层RPC框架基于Akka实现,本文着重分析Flink中的Rpc框架实现机制及梳理其通信流 ...
- C语言之父Dennis Ritchie告诉你:如何成为世界上最好的程序员?
文/Ohans Emmanuel 译/网易云信 想要阅读更多技术干货文章,欢迎关注网易云信博客. 了解网易云信,来自网易核心架构的通信与视频云服务. 我不知道如何成为世界上最好的程序员.但是,我们可以 ...
- 本地线程-ThreadLocal
线程本地存储是一个自动化机制,可以为使用相同变量的每个不同的线程都创建不同的存储.简单来说,就是对于某个变量,针对不同的线程存储不同的值. 实例: import java.util.Random; i ...
- Jenkins与RocketChat集成
Jenkins与RocketChat集成 在Jenkins中安装插件RocketChat Notifier 配置信息 点击Jenkins左侧的系统管理-->系统设置, 找到Global Rock ...
- Programming In Lua 第九章
1, 2, 3, 4, 5, 6, 第6点很关键:先是调用消费者,来唤醒一个协同例程producer,协同例程producer读取一个数据x后调用send.send函数中调用yield(x),该函数将 ...