注意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组件通信,中央控制总线
实现不同组价之间的通信,其实很简单,请看下面步骤
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: 目录, 界面
都引入到app.vue中
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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。