鍍金池/ 問(wèn)答/HTML/ vue 組件通過(guò)bus通訊疑問(wèn)

vue 組件通過(guò)bus通訊疑問(wèn)

1.問(wèn)題

  • 是否非父子非兄弟關(guān)系的組件不能通過(guò)bus通訊?請(qǐng)各位大佬賜教解疑
  • 這個(gè)問(wèn)題的 目的是更深入理解bus 的過(guò)程產(chǎn)生的,請(qǐng) 不要說(shuō)用vuex

2.代碼思路

  • 在路由中注冊(cè)a組件,b組件
  • 在bus.js創(chuàng)建空的 Vue 實(shí)例作為事件總線
  • 訪問(wèn)a組件的頁(yè)面: /aaa。然后點(diǎn)擊按鈕,通過(guò)bus派發(fā)事件
  • 在b組件中監(jiān)聽bus的自定義事件。但在a組件中派發(fā)事件后再訪問(wèn)b組件,b組件的監(jiān)聽函數(shù)未執(zhí)行

如沒能看懂,拜托復(fù)制相關(guān)代碼在本地跑下

3.相關(guān)代碼(基于vue-cli)

組件a

    <template>
      <div>
          組件a
          <button @click="sendMsg">問(wèn)候組件b</button>
      </div>
    </template>
    <script>
    import bus from './bus'
    export default {
        methods: {
            sendMsg() {
                bus.$emit('send', '組件b你好嗎?')
                this.$router.push('/bbb')
            }
        }
    }
    </script>

組件b

<template>
    <div>
        <p>組件b:{{ msg }}</p>
    </div>
</template>
<script type="text/javascript">
import  bus  from './bus'
export default {
    data () {
        return {
            msg: 'msg初始值'
        }
    },
    mounted () {
        bus.$on('send', data => {
            console.log(data)
            console.log(this)
            this.msg = data
        })    
    } 
  
}
</script>

bus.js

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

路由

const aaa = () => import('@/components/zujian/bus/a')
const bbb = () => import('@/components/zujian/bus/b')
export default new Router({
  routes: [{
      path: '/aaa',
      component: aaa
    },
    {
      path: '/bbb',
      component: bbb
    }]
})
回答
編輯回答
還吻

666
.

2018年5月9日 09:19
編輯回答
撥弦

bus的出現(xiàn)就是為了解決非父子組件之間的通信的,而你也說(shuō)過(guò)bus是通過(guò)創(chuàng)建空的 Vue 實(shí)例作為事件總線來(lái)傳遞信息 的,所以:非父子非兄弟關(guān)系的組件都能通過(guò)bus通訊;
你這個(gè)代碼的問(wèn)題:
當(dāng)你問(wèn)候組件b的時(shí)候路由還沒轉(zhuǎn)跳,也就是組件b還沒有實(shí)例化(渲染),就好比只有打電話的,但接電話的都沒有電話,那別人怎么知道你有沒有給我打電話?所以,完成不了通信
有問(wèn)題繼續(xù)來(lái)問(wèn),希望幫到你

2018年7月31日 14:26
編輯回答
瘋浪

eventbus可以實(shí)現(xiàn) 非父子關(guān)系的組件之間的通信. 前提是兩個(gè)組件都已經(jīng)調(diào)用過(guò)mouted鉤子.也就是a / b頁(yè)面都進(jìn)入(渲染)過(guò).

2017年1月7日 00:58
編輯回答
怣人

事件總線當(dāng)然可以,不過(guò)要保證先綁定事件再觸發(fā)事件,這種模式容易造成代碼邏輯混亂。

2017年6月20日 05:05
編輯回答
忠妾

其實(shí)了解一下底層原理就明白了,實(shí)際上就是運(yùn)用了Vue內(nèi)部的事件機(jī)制,可以參考Vue事件機(jī)制。

emit做的事情就是從事件隊(duì)列中找到對(duì)應(yīng)的事件并執(zhí)行,找不到則會(huì)丟棄,所以需要保證在此之前已經(jīng)用on注冊(cè)了事件。

題主這段代碼組件B中的on還沒執(zhí)行過(guò)就已經(jīng)調(diào)用了組件A的emit了。

2017年11月12日 12:56
編輯回答
萌吟

可以參考一下我寫的文章哦,里面就是關(guān)于bus通信的,挺詳細(xì)的,不懂可以問(wèn)一下

2017年10月17日 19:50
編輯回答
六扇門

可以通過(guò)打印生命周期方法來(lái)知道為什么msg沒有更新

你在A執(zhí)行emit的地方
B beforeCreate
B created
B beforeMount
A beforeDestroy
A destroyed
你在B執(zhí)行on的地方
B mounted

可以看到vue-router在切換路由時(shí)的狀態(tài)變化,將on放到emit之前即可

2018年1月31日 22:15