vue2中$emit $on $off實現組件之間的聯動,絕對有你想了解的


在vue2開發中,你肯定會遇到組件之間聯動的問題,現在我們就來說說哪個神奇的指令可以滿足我們的需求。

一、先上實例:

需求:點擊A組件或者B組件可以使C組件的名稱相應發生改變,同樣,點擊A組件也會使對應的B或者C組件顯示選中狀態。

二、說一說$emit、 $on 、$off

1、vm.$on( event, callback )

監聽當前實例上的自定義事件。事件可以由vm.$emit觸發。回調函數會接收所有傳入事件觸發函數的額外參數。

2、vm.$emit( event, […args] )

觸發當前實例上的事件。附加參數都會傳給監聽器回調,如果沒有參數,形式為vm.$emit(event)

3、vm.$off( [event, callback] )

移除自定義事件監聽器。

  • 如果沒有提供參數,則移除所有的事件監聽器;
  • 如果只提供了事件,則移除該事件所有的監聽器;
  • 如果同時提供了事件與回調,則只移除這個回調的監聽器。

三、圖示代碼實現

點擊A組件,B或C組件相應改變(請注意代碼中的EventBus對象,文末會進行解釋,聽哀家一句勸,少踩十年坑)

A組件部分代碼:

                                                                    A組件HTML

<el-submenu index="3">
          <template slot="title">{{SelectPro}}</template>
          <el-menu-item :index="item.number" v-for="(item,index) in ProjectList" :key="index"
                  @click="proClickHandler(item.name,item.ProjectId)">{{item.name}}
          </el-menu-item>
</el-submenu>                        

                                               A組件js

1 EventBus.$emit('refreshPro');

B組件部分代碼:

                          B組件HTML

                                                                                                   

 1 <el-container>
 2         <el-aside width="100%">項目
 3           <table>
 4             <tr>
 5               <td v-for="itemPro in ProjectArr" style="padding-right:10px">
 6                 <div :id= "itemPro.projectId" class="tableTypeItem" style="padding: 10px;width:180px;text-align: left;background-color: #eeeeee" @click="objClickHandler(itemPro.name,itemPro.projectId)">
 7                   <div style="height:10px;border-bottom: 2px  #000000">
 8                     <a>{{itemPro.name}}</a>
 9                   </div>
10                   <hr class="line"/>
11                   <div style="padding:10px 0">
12                     <a>{{itemPro.time}}</a>
13                     <br>
14                     <br>
15                     <a>{{itemPro.user}}</a>
16                   </div>
17                 </div>
18               </td>
19             </tr>
20           </table>
21         </el-aside>
22         <!--<el-main>全部項目-->
23         <!--</el-main>-->
24       </el-container>

                                     B組件js

 1 mounted(){
 2       var _self = this;
 3       EventBus.$on('refreshPro', function () {
 4         _self.changeColor();
 5         _self.GetRecord();
 6         _self.$refs.pie.GetPerInstance();
 7         _self.$refs.bar.GetInstance();
 8       })
 9     },
10 destroyed: function() {
11       EventBus.$off('refreshPro');
12     }

點擊B或者C組件,A組件相應改變:

實現原理為將A組件的數據放到vuex中進行狀態管理,當vuex中的數據改變時,computed的鈎子函數觸發自定義的SelectPro()方法改變A組件的顯示名稱。

                                 A組件代碼

1 computed: {
2       SelectPro() {
3         return this.$store.getters.ProjectName
4       }
5     }

四、切勿忘記的公共實例,大坑,勿踩!

網上百度千篇一律全是使用$emit來實現,但是有一個大坑沒有給別人說明,開始我都按照搜索的結果進行操作,都會出現子組件$emit后父組件沒有監聽到函數的變化,研究了好久才發現$emit和$on的事件必須使用一個空的 Vue 實例作為中央事件總線的實例上,才能夠觸發。即上述代碼中的EventBus。

代碼:                                                                               eventbus.js

1 import Vue from 'vue'
2 
3 //消息總線
4 export default new Vue();

                                                                             A、B組件中引入eventbus.js文件

1 import EventBus from '../../EventBus.js'

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM