非父子组件通信有以下两种方式:中间人模式 && bus中央总线。
<!-- child1 && child2都是组件,并且他们组件之间没有嵌套关系,这种情况下child1和child2需要进行通信,我们称之为非父子组件通信-->
<div id="box">
<child1></child1>
<child2></child2>
</div>
中间人模式
两个组件A,B没有办法通信。我们采用一个中间组件C,让A先和C通信,得到数据后,再由C传递给B
案例:
- film-item组件先通过子传父,将数据传到父组件
this.$emit(“callback”,this.item.synopsis)- 父组件接受数据,并传递给film-detail子组件
handleCallBack(data){ this.detailInfo = data }
<div id="box">
<button @click="handleAjax">ajax</button>
<film-item v-for="item in datalist" :key="item.filmId" :item="item" @callback="handleCallBack"></film-item>
<film-detail :myinfo="detailInfo"></film-detail>
</div>
Vue.component("film-detail",{
props:["myinfo"],/// this.myinfo myinof
template:`
<div class="filminfo">
{{myinfo}}
</div>
`
})
Vue.component("film-item",{
props:["item"],//接受属性, this.item
template:`
<div class="item">
<img :src="item.poster"/>
<div>{{item.name}}</div>
<button @click="handleDetail">详情</button>
</div>
`,
methods:{
handleDetail(){
// console.log(this.item.synopsis)
this.$emit("callback",this.item.synopsis)
}
}
})
new Vue({
el:"#box",
data:{
datalist:[],
detailInfo:""
},
methods:{
handleAjax(){
fetch("json/test.json").then(res=>res.json())
.then(res=>{
// console.log(res)
this.datalist = res.data.films
})
},
handleCallBack(data){
// console.log("父组件触发",data)
this.detailInfo = data
}
}
})
bus中央总线
一个组件负责监听bus.$on,一个组件负责触发bus.$emit
mounted生命周期中进行监听
<div id="box">
<button @click="handleAjax">ajax</button>
<film-item v-for="item in datalist" :key="item.filmId" :item="item"></film-item>
<film-detail></film-detail>
</div>
var bus = new Vue() //中央事件总线
Vue.component("film-detail",{
template:`
<div class="filminfo">
{{info}}
</div>
`,
data(){
return {
info:""
}
},
// 8个生命周期 ---mounted
mounted(){
console.log("mounted","当前挂载到页面上就会执行")
bus.$on("kerwin",(data)=>{
// console.log("kerwin事件",data)
this.info = data
})
}
})
Vue.component("film-item",{
props:["item"],//接受属性, this.item
template:`
<div class="item">
<img :src="item.poster"/>
<div>{{item.name}}</div>
<button @click="handleDetail">详情</button>
</div>
`,
methods:{
handleDetail(){
bus.$emit("kerwin", this.item.synopsis)
}
}
})
new Vue({
el:"#box",
data:{
datalist:[],
},
methods:{
handleAjax(){
fetch("json/test.json").then(res=>res.json())
.then(res=>{
this.datalist = res.data.films
})
}
}
})