1

注意1:事件总线是处理同一路由下复杂的父子关系组件的,如果跨路由是有问题的,因为监听的界面肯定还没有加载,所以这一点要记清楚了。
注意2:为了防止$on监听界面还没有加载完毕可以使用在$emit外面包一层$nextTick等待组件都加载完毕,下面例子会讲解
注意3:经常会出现重复监听的问题,是因为没有关闭监听,随意在今天完毕以后,界面将要销毁的时候关闭监听

beforeDestroy () {
    eventBus.$off('recommendEmit')
  }

1、父组件-->子组件

父组件代码

<child-page :child-msg="data"></child-page>

子组件代码

export default {
  name: 'child',
  props: {
    child-msg: String
  }
};

或者this.$children 访问它所有的子组件, 而且可以递归向下无限访问,

2、子组件-->父组件
发送事件/监听事件
子组件中某函数内发送事件:

this.$emit('toparentevent', 'data');

父组件监听事件:

<Child :msg="msg" @toparentevent="todo()"></Child>

或者使用 this.$parent 可以直接访问该组件的父实例或组件,而且可以递归向上访问

3、父组件直接获取子组件属性或方法
给要调用的子组件起个名字。将名字设置为子组件 ref 属性的值。
<!-- 子组件。 ref的值是组件引用的名称 -->

<child-component ref="aName"></child-component>

父组件中通过 $refs.组件名 来获得子组件,也就可以调用子组件的属性和方法了。

var child = this.$refs.aName
child.属性
child.方法()

最重要的方式:vue组件通信,中央控制总线

clipboard.png

实现不同组价之间的通信,其实很简单,请看下面步骤
1、新建control.js, 注意两行代码写完回车一下要不然报错。

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

2、在需要发射或者监听的界面引入,并使用。
这就是一个中央事件总线,然后我们在需要发送或者监听事件的界面引入这个文件,然后使用里面的$on/$emit来监听和发射消息即可。

import control from './control.js'
// 监听
mounted () {
control.$on('需要监听的事件名称', ()=> {
    // 需要执行的命令
}

// 发射事件
methods () {
    this.$nextTick(() => {
        emitFun() {
            control.$emit("childEmitFun", "参数");
        }
     })
},
beforeDestory () {
    control.$off('childEmitfun')
}

3、实例
A: 目录, 界面

clipboard.png

clipboard.png

都引入到app.vue中

clipboard.png

B: ParentOne.vue

<template>
    <div>
        <br/>
        <br/>
        <v-button @click="emitOneFun()" type="primary">发送给兄弟组件</v-button>
    </div>
</template>
<script>
import center from '../center/center.js'
export default {
    name: "parentOne",
    mounted() {
        
    },
    methods: {
        emitOneFun() {
            this.nextTick(() => {
                center.$emit("emitParentOne");
            })
        }
    }
}
</script>

C: parentTwo.vue

<template>
<div>
    <br/>
    <br/>
    <v-button @click="emitChildrenOneFun" type="primary">发送消息到子组件</v-button>
</div>
</template>
<script>
    import center from "../center/center.js"
    export default {
        mounted () {
            center.$on("emitParentOne", ()=> {
                alert("接收兄弟组件传递过来的信息");
            })
        },
        methods: {
            emitChildrenOneFun () {
                this.nextTick(() => {
                    center.$emit("emitChildrenOne");
                })
            }
        },
        beforeDestory () {
            center.$off('emitChildrenOne')
        }
    }
</script>

D: ChildrenOne.vue

<script>
    import center from "../../center/center.js"
    export default {
        mounted () {
            center.$on("emitChildrenOne", ()=> {
                alert("监听发送childrenOne的事件")
            })
        },
        beforeDestory () {
            center.$off('emitChildrenOne')
        }
    }
</script>
beforecreate : 可以在这加个loading事件 
created :在这结束loading,还做一些初始化,实现函数自执行 
mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情
beforeDestroy: 你确认删除XX吗? destroyed :当前组件已被删除,清空相关内容

事件总线完整实例一个父组件一个子组件
Recommend.vue 父

// 组件之间的通信,要实现兄弟组件,父子组件,父孙组件之间的通信
// 使用系统总线
<template>
  <div>
    <recommend-list></recommend-list>
    <div @click="recommendEmitFun({name: 'zxc'})">事件总线发射事件</div>
  </div>
</template>
<script>
import RecommendList from '../components/RecommendList'
import eventBus from '../assets/eventBus'
export default {
  name: 'Recommend',
  data () {
    return {
    }
  },
  mounted () {
    // 接收事件
    eventBus.$on('recommendListEmit', (params) => {
      console.log(params, 'recommendListEmit')
    })
  },
  methods: {
    recommendEmitFun (params) {
      console.log(params, '发送事件 recommendEmit')
      this.$nextTick(() => {
        eventBus.$emit('recommendEmit', params)
      })
    }
  },
  beforeDestroy () {
    eventBus.$off('recommendListEmit')
  },
  components: {
    RecommendList
  }
}
</script>
<style scoped>

</style>

RecommendList 子

<template>
  <div>
    <div v-for="(item, index) of recommendList" :key="index">
      <div @click="recommendList(index, item)">
        <span>{{index+1}}. </span>
        <span>{{item.title}}</span>
      </div>
    </div>
    <div @click="recommendlistFun()">emit</div>
  </div>
</template>
<script>
import eventBus from '../assets/eventBus'
export default {
  name: 'RecommendList',
  created () {
    eventBus.$on('recommendEmit', (params) => {
      console.log(params, '接受事件总线')
    })
  },
  data () {
    return {
      recommendList: [
        {
          type: 'nba',
          title: '杜兰特复出,勇士大胜猛龙',
          content: '大比分1:3落后的情况下,杜兰特伤愈复出,是否能带领球队获胜?'
        },
        {
          type: 'nba',
          title: '法国跑车帕克宣布退役',
          content: '黄蜂队买断帕克,帕克宣布退役,不再打球。'
        }
      ],
      recommendDetail (index, item) {
        this.$router.push({name: 'detail', params: {id: index, item: item}})
      }
    }
  },
  methods: {
    recommendlistFun () {
      console.log('发送 recommendListEmit')
      this.$nextTick(() => {
        eventBus.$emit('recommendListEmit', {name: 'recommendList'})
      })
    }
  },
  beforeDestroy () {
    eventBus.$off('recommendEmit')
  }
}
</script>

张旭超
1.4k 声望222 粉丝

精通 html+div+css jquery, vue, angularjs, angular2, angular4, ionic, ionic2