您的当前位置:首页vue2利用Bus.js如何实现非父子组件通信详解
广告

vue2利用Bus.js如何实现非父子组件通信详解

2023-12-09 来源:菲特宠物网

前言

大家应该都知道,vue2中废弃了$dispatch和$broadcast广播和分发事件的方法。父子组件中可以用props和$emit()。如何实现非父子组件间的通信,可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发和监听来实现通信和参数传递。下面话不多说了,来一起看看详细的介绍吧。

Bus.js可以是这样

import Vue from 'vue'export default new Vue()

在需要通信的组件都引入Bus.js

import Bus from '../common/js/bus.js'

添加一个button,点击后$emit一个事件

<button @click="toBus">子组件传给兄弟组件</button>

methods

methods: { toBus () { Bus.$emit('on', '来自兄弟组件') } }

另一个组件也import Bus.js 在钩子函数中监听on事件

import Bus from '../common/js/bus.js'export default { data() { return { message: '' } }, mounted() { Bus.$on('on', (msg) => { this.message = msg }) } }

总结

小编还为您整理了以下内容,可能对您也有帮助:

vue 的同级组件间如何传递事件?

在 Vue 中,可以使用事件总线(Event Bus)来实现同级组件之间的通信。事件总线是一种强大的机制,可以实现组件之间的跨级通信,而无需显式地将事件传递到每个组件。你可以在主应用程序中创建一个事件总线,然后将其传递给需要通信的组件。这些组件可以使用事件总线来触发和监听事件。

这里有一篇详细的文章介绍如何使用 Vue 事件总线实现组件间通信。

Vue 面试中常问知识点整理

生命周期:Vue实例从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是Vue的生命周期,各个阶段有相对应的事件钩子。

beforeCreate(创建前),在数据观测和初始化事件还未开始
created(创建后),完成数据观测,属性和方法的运算,初始化事件, $el 属性还没有显示出来
beforeMount(载入前),在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后),在 el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换 el 属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前),在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后),在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前),在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后),在实例销毁之后调用。调用后,所有的事件*会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

注意:
created 阶段的ajax请求与 mounted 请求的区别:前者页面视图未出现,如果请求信息过多,页面会长时间处于白屏状态。
mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 。

初始化组件时,仅执行了 beforeCreate/Created/beforeMount/mounted 四个钩子函数
当改变 data 中定义的变量(响应式变量)时,会执行 beforeUpdate/updated 钩子函数
当切换组件(当前组件未缓存)时,会执行 beforeDestory/destroyed 钩子函数
初始化和销毁时的生命钩子函数均只会执行一次, beforeUpdate/updated 可多次执行

仅当子组件完成挂载后,父组件才会挂载
当子组件完成挂载后,父组件会主动执行一次beforeUpdate/updated钩子函数(仅首次)
父子组件在data变化中是分别监控的,但是在更新props中的数据是关联的
销毁父组件时,先将子组件销毁后才会销毁父组件

组件的初始化(mounted之前)分开进行,挂载是从上到下依次进行
当没有数据关联时,兄弟组件之间的更新和销毁是互不关联的

mixin中的生命周期与引入该组件的生命周期是仅仅关联的,且mixin的生命周期优先执行

1、什么是vue生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
2、vue生命周期的作用是什么?
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
3、vue生命周期总共有几个阶段?
答:它可以总共分为8个阶段:创建前/后、载入前/后、更新前/后、销毁前/销毁后。
5、DOM 渲染在哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter ,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter 。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合 Observer ,Compile和 Watcher 三者,通过 Observer 来监听自己的 model 的数据变化,通过 Compile 来解析编译模板指令(vue中是用来解析 {{}}),最终利用 watcher 搭起observer和 Compile 之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化( input )—>数据 model 变更双向绑定效果。

js实现简单的双向绑定:

1、父组件与子组件传值
父组件传给子组件:子组件通过 props 方法接受数据;
子组件传给父组件: $emit 方法传递参数
2、非父子组件间的数据传递,兄弟组件传值 eventBus ,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。

hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用 window.location.hash 读取。特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
history模式:history采用HTML5的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。

需求一:
在一个列表页中,第一次进入的时候,请求获取数据。
点击某个列表项,跳到详情页,再从详情页后退回到列表页时,不刷新。
也就是说从其他页面进到列表页,需要刷新获取数据,从详情页返回到列表页时不要刷新。
解决方案
在 App.vue设置:

假设列表页为 list.vue ,详情页为 detail.vue ,这两个都是子组件。
我们在 keep-alive 添加列表页的名字,缓存列表页。
然后在列表页的 created 函数里添加ajax请求,这样只有第一次进入到列表页的时候才会请求数据,当从列表页跳到详情页,再从详情页回来的时候,列表页就不会刷新。
这样就可以解决问题了。

需求二:
在需求一的基础上,再加一个要求:可以在详情页中删除对应的列表项,这时返回到列表页时需要刷新重新获取数据。
我们可以在路由配置文件上对 detail.vue 增加一个 meta 属性。

这个 meta 属性,可以在详情页中通过 this.$route.meta.isRefresh 来读取和设置。
设置完这个属性,还要在 App.vue 文件里设置 watch 一下 $route 属性。

这样就不需要在列表页的 created 函数里用 ajax 来请求数据了,统一放在 App.vue 里来处理。
触发请求数据有两个条件:
从其他页面(除了详情页)进来列表时,需要请求数据。
从详情页返回到列表页时,如果详情页 meta 属性中的 isRefresh 为 true ,也需求重新请求数据。
当我们在详情页中删除了对应的列表项时,就可以将详情页 meta 属性中的 isRefresh 设为 true 。这时再返回到列表页,页面会重新刷新。

1、css只在当前组件起作用
答:在 style 标签中写入 scoped 即可 例如: <style scoped></style>
2、v-if 和 v-show 区别
答: v-if 按照条件是否渲染, v-show 是 display 的 block 或 none ;
3、 $route 和 $router 的区别
答: $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。而 $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等。

Vue 面试中常问知识点整理

生命周期:Vue实例从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是Vue的生命周期,各个阶段有相对应的事件钩子。

beforeCreate(创建前),在数据观测和初始化事件还未开始
created(创建后),完成数据观测,属性和方法的运算,初始化事件, $el 属性还没有显示出来
beforeMount(载入前),在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后),在 el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换 el 属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前),在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后),在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前),在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后),在实例销毁之后调用。调用后,所有的事件*会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

注意:
created 阶段的ajax请求与 mounted 请求的区别:前者页面视图未出现,如果请求信息过多,页面会长时间处于白屏状态。
mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 。

初始化组件时,仅执行了 beforeCreate/Created/beforeMount/mounted 四个钩子函数
当改变 data 中定义的变量(响应式变量)时,会执行 beforeUpdate/updated 钩子函数
当切换组件(当前组件未缓存)时,会执行 beforeDestory/destroyed 钩子函数
初始化和销毁时的生命钩子函数均只会执行一次, beforeUpdate/updated 可多次执行

仅当子组件完成挂载后,父组件才会挂载
当子组件完成挂载后,父组件会主动执行一次beforeUpdate/updated钩子函数(仅首次)
父子组件在data变化中是分别监控的,但是在更新props中的数据是关联的
销毁父组件时,先将子组件销毁后才会销毁父组件

组件的初始化(mounted之前)分开进行,挂载是从上到下依次进行
当没有数据关联时,兄弟组件之间的更新和销毁是互不关联的

mixin中的生命周期与引入该组件的生命周期是仅仅关联的,且mixin的生命周期优先执行

1、什么是vue生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
2、vue生命周期的作用是什么?
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
3、vue生命周期总共有几个阶段?
答:它可以总共分为8个阶段:创建前/后、载入前/后、更新前/后、销毁前/销毁后。
5、DOM 渲染在哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter ,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter 。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合 Observer ,Compile和 Watcher 三者,通过 Observer 来监听自己的 model 的数据变化,通过 Compile 来解析编译模板指令(vue中是用来解析 {{}}),最终利用 watcher 搭起observer和 Compile 之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化( input )—>数据 model 变更双向绑定效果。

js实现简单的双向绑定:

1、父组件与子组件传值
父组件传给子组件:子组件通过 props 方法接受数据;
子组件传给父组件: $emit 方法传递参数
2、非父子组件间的数据传递,兄弟组件传值 eventBus ,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。

hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用 window.location.hash 读取。特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
history模式:history采用HTML5的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。

需求一:
在一个列表页中,第一次进入的时候,请求获取数据。
点击某个列表项,跳到详情页,再从详情页后退回到列表页时,不刷新。
也就是说从其他页面进到列表页,需要刷新获取数据,从详情页返回到列表页时不要刷新。
解决方案
在 App.vue设置:

假设列表页为 list.vue ,详情页为 detail.vue ,这两个都是子组件。
我们在 keep-alive 添加列表页的名字,缓存列表页。
然后在列表页的 created 函数里添加ajax请求,这样只有第一次进入到列表页的时候才会请求数据,当从列表页跳到详情页,再从详情页回来的时候,列表页就不会刷新。
这样就可以解决问题了。

需求二:
在需求一的基础上,再加一个要求:可以在详情页中删除对应的列表项,这时返回到列表页时需要刷新重新获取数据。
我们可以在路由配置文件上对 detail.vue 增加一个 meta 属性。

这个 meta 属性,可以在详情页中通过 this.$route.meta.isRefresh 来读取和设置。
设置完这个属性,还要在 App.vue 文件里设置 watch 一下 $route 属性。

这样就不需要在列表页的 created 函数里用 ajax 来请求数据了,统一放在 App.vue 里来处理。
触发请求数据有两个条件:
从其他页面(除了详情页)进来列表时,需要请求数据。
从详情页返回到列表页时,如果详情页 meta 属性中的 isRefresh 为 true ,也需求重新请求数据。
当我们在详情页中删除了对应的列表项时,就可以将详情页 meta 属性中的 isRefresh 设为 true 。这时再返回到列表页,页面会重新刷新。

1、css只在当前组件起作用
答:在 style 标签中写入 scoped 即可 例如: <style scoped></style>
2、v-if 和 v-show 区别
答: v-if 按照条件是否渲染, v-show 是 display 的 block 或 none ;
3、 $route 和 $router 的区别
答: $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。而 $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等。

vue websocket是怎么实现即时通讯的?

Vue.js是一种流行的前端框架,它提供了一系列的工具和库,使得构建实时通信的Web应用程序变得容易。在Vue.js中,实现即时通讯的方式之一就是使用WebSocket。

WebSocket是一种基于TCP的协议,它允许在客户端和服务器之间进行双向通信。在Vue.js中,使用WebSocket可以实现以下的功能:

    服务端和客户端之间的实时数据传输:WebSocket可以实现服务端向客户端实时推送数据,从而实现实时通讯。

    长连接:WebSocket采用长连接的方式,使得客户端和服务端之间可以保持长时间的通讯,而不需要频繁地建立和关闭连接。

    在Vue.js中,实现WebSocket通信的步骤如下:

    在Vue.js应用程序中引入WebSocket库,如Socket.IO。

    在Vue.js组件中创建WebSocket对象,指定连接的URL和其他选项。

    通过WebSocket对象的方法,如send()方法,向服务端发送消息,并处理服务端返回的消息。

    在Vue.js组件的生命周期函数中,对WebSocket进行初始化、连接、关闭等操作。

在使用Vue.js进行WebSocket通信时,需要注意以下几点:

    WebSocket通信是基于事件的,需要注册事件处理函数来处理WebSocket的连接、断开连接、收到消息等事件。

    在Vue.js组件中,可以使用data属性来维护WebSocket的连接状态和消息数据。

    Vue.js中可以使用computed属性或watcher来处理WebSocket数据的变化,从而实现组件中数据的实时更新。

综上所述,Vue.js中通过WebSocket实现即时通讯的方式相对比较简单,但需要对WebSocket的原理和相关的事件、方法等有一定的了解。

vue websocket是怎么实现即时通讯的?

Vue.js是一种流行的前端框架,它提供了一系列的工具和库,使得构建实时通信的Web应用程序变得容易。在Vue.js中,实现即时通讯的方式之一就是使用WebSocket。

WebSocket是一种基于TCP的协议,它允许在客户端和服务器之间进行双向通信。在Vue.js中,使用WebSocket可以实现以下的功能:

    服务端和客户端之间的实时数据传输:WebSocket可以实现服务端向客户端实时推送数据,从而实现实时通讯。

    长连接:WebSocket采用长连接的方式,使得客户端和服务端之间可以保持长时间的通讯,而不需要频繁地建立和关闭连接。

    在Vue.js中,实现WebSocket通信的步骤如下:

    在Vue.js应用程序中引入WebSocket库,如Socket.IO。

    在Vue.js组件中创建WebSocket对象,指定连接的URL和其他选项。

    通过WebSocket对象的方法,如send()方法,向服务端发送消息,并处理服务端返回的消息。

    在Vue.js组件的生命周期函数中,对WebSocket进行初始化、连接、关闭等操作。

在使用Vue.js进行WebSocket通信时,需要注意以下几点:

    WebSocket通信是基于事件的,需要注册事件处理函数来处理WebSocket的连接、断开连接、收到消息等事件。

    在Vue.js组件中,可以使用data属性来维护WebSocket的连接状态和消息数据。

    Vue.js中可以使用computed属性或watcher来处理WebSocket数据的变化,从而实现组件中数据的实时更新。

综上所述,Vue.js中通过WebSocket实现即时通讯的方式相对比较简单,但需要对WebSocket的原理和相关的事件、方法等有一定的了解。

vue 组件通信方式 ,父子、隔代、兄弟 三类通信,六种方法

Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面分别介绍每种通信方式且会说明此种方法可适用于哪类组件间通信。

父组件注入,子组件接收。
这种方法是 Vue 组件的基础,相信大部分同学耳闻能详,所以此处就不举例展开介绍。

ref :如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
$parent / $children :访问父 / 子实例

$attrs: 包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 ( class 和 style 除外 )。
当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。

$listeners :包含了父作用域中的 (不含 .native 修饰器的) v-on 事件*。它可以通过 v-on="$listeners" 传入内部组件

祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

这种方法通过一个空的 Vue 实例作为*事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

vuex的详细使用方法: vuex管理状态仓库使用详解

a.vue 引用了一个detail组件

第一步:首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。

两个初始化事件中心的方法:

第二步:创建了 EventBus ,接下来你需要做到的就是在你的组件中加载它,并且调用同一个方法,就如你在父子组件中互相传递消息一样。

假设你有两个Vue页面需要通信: A 和 B ,A页面 在按钮上面绑定了点击事件,发送一则消息,想通知 B页面。

接下来,我们需要在 B页面 中接收这则消息。

同理我们也可以在 B页面 向 A页面 发送消息。这里主要用到的两个方法:

如果使用不善,EventBus会是一种灾难,到底是什么样的“灾难”了?大家都知道vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。还要就是如果业务有反复操作的页面,EventBus在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理EventBus在项目中的关系。通常会用到,在vue页面销毁时,同时移除EventBus事件监听。
如果想移除事件的监听,可以像下面这样操作:

$on 事件是不会自动清楚销毁的,需要我们手动来销毁,否则在b组件每次加载一次就会创建一个监听,会重复监听到数据。
可以使用 EventBus.$off('aMsg') 来移除应用内所有对此某个事件的监听。
或者直接调用 EventBus.$off() 来移除所有事件频道,不需要添加任何参数 。

因为页面跳转的时候 ,a页面在之前已经emit了,但是b页面首次并没有created,b页面还监听不到。
可以把A页面组件中的emit事件写在beforeDestory中去。因为这个时候,B页面组件已经被created了,也就是我们写的$on事件已经可以触发了

所以可以,在beforeDestory的时候,$emit事件。例如:

【参考eventbus实战记录: https://www.jianshu.com/p/fde85549e3b0 】

vue 组件通信方式 ,父子、隔代、兄弟 三类通信,六种方法

Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面分别介绍每种通信方式且会说明此种方法可适用于哪类组件间通信。

父组件注入,子组件接收。
这种方法是 Vue 组件的基础,相信大部分同学耳闻能详,所以此处就不举例展开介绍。

ref :如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
$parent / $children :访问父 / 子实例

$attrs: 包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 ( class 和 style 除外 )。
当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。

$listeners :包含了父作用域中的 (不含 .native 修饰器的) v-on 事件*。它可以通过 v-on="$listeners" 传入内部组件

祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

这种方法通过一个空的 Vue 实例作为*事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

vuex的详细使用方法: vuex管理状态仓库使用详解

a.vue 引用了一个detail组件

第一步:首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。

两个初始化事件中心的方法:

第二步:创建了 EventBus ,接下来你需要做到的就是在你的组件中加载它,并且调用同一个方法,就如你在父子组件中互相传递消息一样。

假设你有两个Vue页面需要通信: A 和 B ,A页面 在按钮上面绑定了点击事件,发送一则消息,想通知 B页面。

接下来,我们需要在 B页面 中接收这则消息。

同理我们也可以在 B页面 向 A页面 发送消息。这里主要用到的两个方法:

如果使用不善,EventBus会是一种灾难,到底是什么样的“灾难”了?大家都知道vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。还要就是如果业务有反复操作的页面,EventBus在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理EventBus在项目中的关系。通常会用到,在vue页面销毁时,同时移除EventBus事件监听。
如果想移除事件的监听,可以像下面这样操作:

$on 事件是不会自动清楚销毁的,需要我们手动来销毁,否则在b组件每次加载一次就会创建一个监听,会重复监听到数据。
可以使用 EventBus.$off('aMsg') 来移除应用内所有对此某个事件的监听。
或者直接调用 EventBus.$off() 来移除所有事件频道,不需要添加任何参数 。

因为页面跳转的时候 ,a页面在之前已经emit了,但是b页面首次并没有created,b页面还监听不到。
可以把A页面组件中的emit事件写在beforeDestory中去。因为这个时候,B页面组件已经被created了,也就是我们写的$on事件已经可以触发了

所以可以,在beforeDestory的时候,$emit事件。例如:

【参考eventbus实战记录: https://www.jianshu.com/p/fde85549e3b0 】

Vue3 和Vue2的组件通信方式,建议收藏

先来看看Vue3的几种组件通信方式:

下面分别介绍这几种方式的写法:

1、props

2、$emit

3、expose / ref

4、attrs

5、v-model

6. provide / inject

接下来是Vue2.x 组件通信使用方法:

1、 props

2、.sync

3、v-model

4、ref

5、$emit / v-on

6、children/parent

7、EventBus

8、Vuex (这个就不举例子了........懂的都懂!)

创作不易,你的关注就是我前进的动力![奋斗][奋斗]

vue组件间通信

在父组件页面使用 v-bind: 或 : 将数据传递给子组件,子组件通过 props 获取父组件传递过来的值。

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法---- $attrs ;

示例:
我们向子组件son传递5个属性,再由子组件son向孙子组件grandson传递4个属性(这4个组件不做任何处理,只是传递),son组件向grandson组件传递的那4个属性就可以使用 v-bind=$attrs 。

通常和 $attrs 配合使用。

简单来说,使用 interitAttrs: false 子组件的$attrs不会被当做是html属性渲染到根元素上,防止修改html同名属性。

在子组件页面使用 this.$emit('自定义事件名', 数据); 将数据传递给父组件,父组件通过 @自定义事件名="事件处理方法名" 或者 v-on:自定义事件名="事件处理方法名" 获取子组件传递过来的值。

若公共组件被很多组件调用且抛出的自定义事件都不同,此时就可以使用 $listeners ;根据父组件调用的事件去决定抛出哪个自定义事件。

EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的灾难,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。 更多EventBus

vuex官网

Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State的变化,渲染到视图上。

provide / inject 官网介绍

vue2.2.0 新增API,这对选项需要一起使用, 以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效 。如果你熟悉 React,这与 React 的上下文特性很相似。
provide / inject API 主要解决了跨级组件间的通信问题。 官网提供了很详细的介绍,这里直接上图

由图8-1可知, this.$children 获取到的是一个vue实列数组

由图8-2可知, this.$parent 获取到的是直接父实例

由图8-3可知, this.$refs 返回的是一个使用ref注册过的对象

sessionStorage、localStorage也能实现通信,但是需要监听storage的变化,如何监听storage的变化,之前有写过这篇文章 vue 监听localStorage、sessionStorage变化 ,这里就不赘述了。

vue组件间通信的六种方式

vue组件间通信

在父组件页面使用 v-bind: 或 : 将数据传递给子组件,子组件通过 props 获取父组件传递过来的值。

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法---- $attrs ;

示例:
我们向子组件son传递5个属性,再由子组件son向孙子组件grandson传递4个属性(这4个组件不做任何处理,只是传递),son组件向grandson组件传递的那4个属性就可以使用 v-bind=$attrs 。

通常和 $attrs 配合使用。

简单来说,使用 interitAttrs: false 子组件的$attrs不会被当做是html属性渲染到根元素上,防止修改html同名属性。

在子组件页面使用 this.$emit('自定义事件名', 数据); 将数据传递给父组件,父组件通过 @自定义事件名="事件处理方法名" 或者 v-on:自定义事件名="事件处理方法名" 获取子组件传递过来的值。

若公共组件被很多组件调用且抛出的自定义事件都不同,此时就可以使用 $listeners ;根据父组件调用的事件去决定抛出哪个自定义事件。

EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的灾难,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。 更多EventBus

vuex官网

Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State的变化,渲染到视图上。

provide / inject 官网介绍

vue2.2.0 新增API,这对选项需要一起使用, 以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效 。如果你熟悉 React,这与 React 的上下文特性很相似。
provide / inject API 主要解决了跨级组件间的通信问题。 官网提供了很详细的介绍,这里直接上图

由图8-1可知, this.$children 获取到的是一个vue实列数组

由图8-2可知, this.$parent 获取到的是直接父实例

由图8-3可知, this.$refs 返回的是一个使用ref注册过的对象

sessionStorage、localStorage也能实现通信,但是需要监听storage的变化,如何监听storage的变化,之前有写过这篇文章 vue 监听localStorage、sessionStorage变化 ,这里就不赘述了。

vue组件间通信的六种方式

详解如何实现vuex(详细教程)

本篇文章主要介绍了如何实现一个简单的 vuex,现在分享给大家,也给大家做个参考。

首先我们需要知道为何要使用 vuex。父子组件通信用 prop 和自定义事件可以搞定,简单的非父子组件通信用 bus(一个空的 Vue 实例)。那么使用 vuex 就是为了解决复杂的非父子组件通信。

仅仅会使用 vuex 没什么,看过文档敲敲代码大家都会。难道你就不想知道 vuex 是如何实现的?!

抛开 vuex 的源码,我们先来想想如何实现一个简单的 "vuex"。有多简单呢,我不要 getter、mutation、action 等,我只要 state 就行了。

非父子组件通信

在实现之前,我们得来温故一下 bus 的实现,借用官网的例子:

var bus = new Vue()

// 触发组件 A 中的事件

bus.$emit('id-selected', 1)

// 在组件 B 创建的钩子中监听事件

bus.$on('id-selected', function (id) {

// ...

})遥想当年,实例化后的 bus 不知放哪好,最后无奈将其放到了 window 下,一直 window.bus 的使用。虽然这样也没问题,但还是影响到了全局作用域。

突然的某一天,我发现可以挂载在 vue 的根实例下(从此告别 window.bus),于是便有了:

var app = new Vue({

el: '#app',

bus: bus

})

// 使用 bus

app.$options.bus

// or

this.$root.$options.bus然后又发现了,bus 其实不只是 on 事件才可以通信。其实 bus 是一个 Vue 实例,其中 data 是响应的。比如在 app 这个根实例下有两个非父子组件,都使用到了 bus 的 data,那么它们是响应同步的。

var bus = new Vue({

data: {

count: 0

}

})以上,子组件 a 修改了 count,如果子组件 b 有用到 count,那么它就能响应到最新 count 的值。

说了这么多,你还没发现吗?这个不就是实现了非组件之间通信,vuex 的 state 吗?!

封装 bus

是的,把刚刚的 bus 封装一下,这个就是一个最简单的 "vuex" (仅仅只有 state 的功能)。首先,我们将有一个根实例 app ,实例下有两个非父子组件 childA 和 childB 。

html 代码的实现如下:

<p id="app">

<child-a></child-a>

<child-b></child-b>

</p>非父子组件的实现

然后是两个非父子组件和 app 的实现,子组件都使用到了 bus 的 count,这里用 store.state 表示,跟 vuex 一致:

// 待实现

const store = new Store(Vue, {

state: {

count: 0

}

})

// 子组件 a

const childA = {

template: '<button @click="handleClick">click me</button>',

methods: {

handleClick () {

this.$store.state.count += 1

}

}

}

// 子组件 b

const childB = {

template: '<p>count: {{ count }}</p>',

computed: {

count () {

return this.$store.state.count

}

}

}

new Vue({

el: '#app',

components: {

'child-a': childA,

'child-b': childB

},

store: store

})看到代码里还有一个 Store 待实现。所需要的参数,因为这里懒得用 Vue.use() ,所以直接将 Vue 作为参数传入以供使用,然后第二个参数跟我们使用 vuex 传入的参数一致。

Store 的实现

接下来就是 Store 的实现,两步实现:

创建一个 bus 实例;

让子组件都能访问到 this.$store。

第 1 步骤上面已经有了,第 2 步骤主要用到了 Vue.mixin 来全局混入,但仅仅只是找到有 store 的根实例并赋值 Vue 原型上的 store,也能够让根实例 app 不用专门写 mixins 混入。

class Store {

constructor (Vue, options) {

var bus = new Vue({

data: {

state: options.state

}

})

this.install(Vue, bus)

}

install (Vue, bus) {

Vue.mixin({

beforeCreate () {

if (this.$options.store) {

Vue.prototype.$store = bus

}

}

})

}

}实现的 Store 就是一个简单的 "vuex",它拥有了 vuex 的 state,足够让非父子组件之间进行简单通信。

在 Store 的构造函数里创建一个 bus 实例,并将其注入 Vue 的原型,实现了组件都能访问到 this.$store 即 bus 实例。 this.$store 就是一个 Vue 实例,所以访问了 this.$store.state.count 实际上就是访问到了 data,从而实现了非父子组件之间的响应同步。全部源码参考这里 。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用node应用中timing-attack存在哪些安全漏洞

在vue组件传递对象中实现单向绑定,该怎么做?

在Vue组件中如何使用 TypeScript的方法(详细教程)

vue兄弟组件之间方法调用

方法一:

父组件 index.vue   中含有两个兄弟组件 business.vue  及  detail.vue

当 business.vue中主协办分配选择完成后 需要刷新   detail.vue中的数据

在父组件中 的 business.vue组件上 定义触发的方法  <business @updateDate='updateDate'></business>

在父组件中 的  detail.vue组件上 定义触发的方法  < detail.vue ref='detail'></detail>

在兄弟组件中 主协办分配选择完成后showUserAssignData方法去触发父组件 index.vue的updateDate方法

在父组件中 updateDate方法去触发detail.vue组件中刷洗数据的方法

 方法二:采用公共bus方法---js方法

第二个子组件需要调用第二个子组件方法

在main.js中 注册一个公共实例并绑定到原型上

 Vue.prototype.$bus = new Vue()

在第一个子组件中注册一个方法 在created 或者mounted中注册

在兄弟组件中触发该方法

菲特宠物网还为您提供以下相关内容希望对您有帮助:

Vue3 和Vue2的组件通信方式,建议收藏

5、v-model 6. provide / inject 接下来是Vue2.x 组件通信使用方法: 1、 props 2、.sync 3、v-model 4、ref 5、$emit / v-on 6、children/parent 7、EventBus 8、Vuex (这个就不举例子了...懂的都懂...

vue 的同级组件间如何传递事件?

在 Vue 中,可以使用事件总线(Event Bus)来实现同级组件之间的通信。事件总线是一种强大的机制,可以实现组件之间的跨级通信,而无需显式地将事件传递到每个组件。你可以在主应用程序中创建一个事件总线,然后将其传递给需...

vue2组件通信之$parent/$root

兄弟组件之间通信可通过共同祖辈搭桥,$parent或$root 组件A监听数据 this.$parent.$on('foo',msg=&gt;{ console.log(msg)})this.$root.$on('foo',msg=&gt;{ console.log(msg)})组件B传递数据 this.$parent.$emit('fo...

vue-bus实现兄弟组件通讯

第一步:使用npm install vue-bus --save 第二步:在main.js进行全局注册 第三步:在一个页面引用两个兄弟组件 第四步:使用emit进行参数传递 第五步:在created或mounted生命周期钩子,执行事件监听。最后记得将触发的...

vue组件间通信

由图8-1可知, this.$children 获取到的是一个vue实列数组 由图8-2可知, this.$parent 获取到的是直接父实例 由图8-3可知, this.$refs 返回的是一个使用ref注册过的对象 sessionStorage、localStorage也能实现通信,...

详解如何实现vuex(详细教程)

非父子组件通信在实现之前,我们得来温故一下 bus 的实现,借用官网的例子:var bus = new Vue()// 触发组件 A 中的事件bus.$emit('id-selected', 1)// 在组件 B 创建的钩子中监听事件bus.$on('id-selected', ...

vue 组件通信方式 ,父子、隔代、兄弟 三类通信,六种方法

第一步:首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。两个初始化事件中心的方法:第二步:创建了 EventBus ,接下来你需要做到的就是在你的组件中加载它,并且调用同一个方法,就如你在父子组件中...

vue兄弟组件之间方法调用

在父组件中 updateDate方法去触发detail.vue组件中刷洗数据的方法  方法二:采用公共bus方法---js方法 第二个子组件需要调用第二个子组件方法 在main.js中 注册一个公共实例并绑定到原型上  Vue....

Vuex的使用及组件通信方式

Vue组件简单常用的通信方式有以下几种:1、父子通信:父向子传值,通过props;子向父传值通过events ($emit);父调用子方法通过ref;provide / inject。2、兄弟通信:bus 3、跨级嵌套通信:bus;provide / inject等。Vuex...

vue如何调用公共组件vue公共组件

如果一个通用组件被很多组件调用,抛出的自定义事件不一样,可以使用$listeners根据父组件调用的事件决定要引发哪个自定义事件。EventBus也叫事件总线。在Vue中,EventBus可以作为通信桥的概念,就像所有组件共享同一个事件中心,...

Top