案例完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../lib/vue.js"></script>
<style>
div img{
width: 100px;
}
.active{
width: 300px;
min-height: 200px;
background-color: yellow;
position: fixed;
right: 50px;
top: 100px;
border: 1px solid blue;
}
</style>
</head>
<body>
<div id="box">
<button @click="handleAjax">ajax</button>
<film-item v-for="item in datalist" :key="item.filmId" :mydata="item"></film-item>
<film-detail></film-detail>
</div>
<script>
//定义bus
var bus = new Vue()
//bus中有两个方法:
//bus.$on() 监听
//bus.$emit() 触发
Vue.component("filmItem",{
props:['mydata'],
template:`
<div>
<img :src="mydata.poster">
{{mydata.name}}
<button @click="handleClick">详情</button>
</div>
`,
methods:{
handleClick(){
console.log(this.mydata.synopsis)
//发布者
bus.$emit("yiyi",this.mydata.synopsis)
}
}
})
Vue.component("filmDetail",{
data(){
return{
info:""
}
},
// 生命周期,组件创建完就会触发
mounted(){
//订阅者,监听要在发布之前就做好,不然有可能监听不到,
bus.$on("yiyi",(data)=>{
console.log("111",data)
this.info=data
})
},
template:`
<div class="active">
{{info}}
</div>
`,
})
new Vue({
el:"#box",
data:{
datalist:[],
},
methods:{
handleAjax(){
fetch("test.json").then(res=>res.json())
.then(res=>{
console.log(res.data.films)
this.datalist=res.data.films
})
},
}
})
</script>
</body>
</html>
结果:
- 上面的代码实现了兄弟之间的通信,中间人不再是“父组件”,而是通过 bus中央事件总线 来实现的;
bus中央事件总线引入:
如果说是简单的兄弟之间的通信,可以用父组件进行通信,但是如果说稍微复杂一点呢,叔侄之间的通信呢,用父组件做中间人就很麻烦了;
有两种办法:
- bus中央事件总线 和 vuex状态管理;简单一点的用前者,更复杂一点的用后者;
- 这一篇我们引入了 bus中央事件总线 ;
bus的原理:
- 原理很简单就是订阅发布模式;就是定义一个bus--一个vue实例,然后通信的两端,一个是发布者,一个是订阅者;
- 发布者是控制事件的触发;
- 订阅者是监听事件,事件触发后,执行函数代码;
- bus里有两个方法,bus.$on()、bus.$emit();
- bus.$on():是监听方法,给订阅者用来监听事件;
- bus.$emit():是事件触发方法,给发布者来进行事件触发;
- 关系简单用“bus”,很复杂用“vuex” ;
- 原理图:
关键代码说明:
首先定义bus:
var bus = new Vue()
- 要使用bus,先定义bus,是一个Vue实例;
发布者事件触发:
//发布者
bus.$emit("yiyi",this.mydata.synopsis)
- 要触发的事件是“yiyi”,这个事件名是自定义的,后面参数是要传给订阅者的参数;
订阅者监听到事件触发后,执行函数:
// 生命周期,组件创建完就会触发
mounted(){
//订阅者,监听要在发布之前就做好,不然有可能监听不到,
bus.$on("yiyi",(data)=>{
console.log("111",data)
this.info=data
})
},
- 订阅者的监听方法要在发布者触发之前就定义好,不然有可能监听不到;
- mounted(){}:是Vue中的一个生命周期,在组件创建完以后就自动被触发;
- 所以我们把监听方法放在 mounted(){}去执行,当组件创建完,监听方法就准备好监听了;
- 监听方法第一个参数是要监听的事件,第二个参数是一个回调函数,回调函数的参数是用来接收发布者传来的实参,然后这个data参数是临时的,不能显示在页面上,所以订阅者要重新定义一个状态来接收它,也就是代码中的info;