最近在學(xué)習(xí)Vue,組件化后不同組件之間如何通信部逮,記錄一下娜汁。
- Vue中組件通信時(shí),數(shù)據(jù)流只能由父級(jí)傳遞給子級(jí)兄朋,通過props掐禁,子級(jí)傳遞信息給父級(jí),通過$emit颅和。
- 只有父子間能直接通信傅事,兄弟(同級(jí))之間,爺孫(隔代)之間都不能直接傳遞信息峡扩,只能利用父子通信來傳遞蹭越。
父子組件
子組件接受父組件的數(shù)據(jù)時(shí),通過定義props來實(shí)現(xiàn)教届。子組件對(duì)父組件傳遞信息時(shí)响鹃,通過事件來傳遞。如下面的示例
http://js.jirengu.com/zuzikasoxe/2/edit
<div id="app">
<child :title="message" @click-child="message2 += $event "></child>
{{message2}}
</div>
Vue.component('child',{
props:['title'],
data(){
return{
msg: '+child發(fā)出的數(shù)據(jù)',
}
},
template:`<div>
<hr><div>
{{title}}<button @click="$emit('click-child',msg)">child</button>
<hr>
</div>
`
})
let app = new Vue({
el: "#app",
data: {
message: '父組件的一個(gè)數(shù)據(jù)',
message2: 'Hello',
},
})
子組件中通過props中的title案训,綁定了父組件中的message买置,實(shí)現(xiàn)了數(shù)據(jù)傳遞。而通過$emit()將點(diǎn)擊事件通知了父組件强霎,實(shí)現(xiàn)了父子之間的通信忿项。
爺孫通信
爺爺和孫子是不能直接通信的,只能通過爺爺傳給兒子,兒子傳給孫子倦卖。孫子傳給兒子洒擦,兒子傳給爺爺這樣進(jìn)行通信。
http://js.jirengu.com/jaquhoseqo/3/edit
<div id="app">
{{message2}}
<child :title="message" @click-add="message2 += $event" @click-grand-add="message2 += $event"></child>
</div>
Vue.component('child', {
props: ['title'],
data() {
return {
msg: '+child發(fā)出的數(shù)據(jù)',
}
},
template: `
<div>
<hr>
{{title}}
<button @click="$emit('click-add',msg)">child++</button>
<grand-son :tit="title" @click-grand-add="$emit('click-grand-add',$event)"></grand-son>
</div>
`
})
Vue.component('grand-son', {
props: ['tit'],
data() {
return {
msg: '+grandSon發(fā)出的數(shù)據(jù)',
}
},
template: `
<div>
<hr>
{{tit}}
<button @click="$emit('click-grand-add',msg)">grandSon++</button>
</div>
`
})
let app = new Vue({
el: "#app",
data: {
message: '父組件的一個(gè)數(shù)據(jù)',
message2: 'Hello',
},
})
兒子通過props得到爺爺?shù)臄?shù)據(jù)怕膛,孫子再通過props得到兒子的數(shù)據(jù)熟嫩,進(jìn)而得到爺爺?shù)臄?shù)據(jù)。孫子發(fā)出數(shù)據(jù)時(shí)褐捻,$emit首先通知到兒子掸茅,再通知到爺爺,最后爺爺進(jìn)行相應(yīng)操作柠逞。
兄弟(同級(jí))組件間通信
定義一個(gè)公共的vue實(shí)例昧狮,一個(gè)組件傳遞數(shù)據(jù)時(shí),向這個(gè)實(shí)例發(fā)送$emit通知板壮,另一個(gè)組建用這個(gè)實(shí)例監(jiān)聽事件逗鸣,進(jìn)行相應(yīng)的操作。
https://jsfiddle.net/50wL7mdz/527445/
<script src="https://unpkg.com/vue"></script>
<div id="app">
{{message}}
<child></child>
<child2></child2>
</div>
let bus = new Vue()
Vue.component('child', {
props: ['title'],
template: `
<div>
<hr>這里是child1
<button @click="fn">關(guān)閉button2</button>
</div>
`,
methods: {
fn(){
bus.$emit('click-child','child1想關(guān)閉child2')
}
}
})
Vue.component('child2', {
props: ['title'],
data() {
return {
msg: '這里是child2',
}
},
created: function() {
bus.$on('click-child',this.fn)
},
methods: {
fn(value){
this.msg += value
}
},
template: `
<div>
<hr>{{msg}}
<button>button2</button>
</div>
`
})
let app = new Vue({
el: "#app",
data: {
message: 'Hello',
},
})
這段代碼中bus就是一個(gè)公共的容器绰精,使同級(jí)的兄弟組件中進(jìn)行通信撒璧。