zoukankan      html  css  js  c++  java
  • 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;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'
  • 相关阅读:
    Java实现判断单联通(强连通缩点+拓扑排序)Going from u to v or from v to u
    Java实现判断单联通(强连通缩点+拓扑排序)Going from u to v or from v to u
    Java实现判断单联通(强连通缩点+拓扑排序)Going from u to v or from v to u
    Java实现判断单联通(强连通缩点+拓扑排序)Going from u to v or from v to u
    判断一个窗体是否被完全遮挡(比较有意思,但这招有什么用呢?)
    Delphi中用MessageBox()API函数做倒计时对话框(使用Hook安装CBTHookCallback,计时器更改文字,SetWindowText API真正修改文字,引用未知函数)good
    Delphi&C#代码模拟“显示桌面”的功能(使用CreateOleObject('Shell.Application'))
    LLVM和GCC的区别(LLVM提供了模块化的编译模块,非常有利于重用,以前的编译器都没有做到这一点)
    Delphi产生任务栏图标【TNotifyIconData】
    国内外10大项目外包平台
  • 原文地址:https://www.cnblogs.com/kadima-zy/p/emit.html
Copyright © 2011-2022 走看看