前言
我們平時做一個工程項目怖现,每個功能模塊之間是相互獨立的厌小,彼此之間按理歷史自理門戶的,但是難眠會相互通信,而且還要向“皇上”(中央)匯報工作疯搅。vue組件是一個非常強大的功能罪治,而組件實例的作用域是相互獨立的浴井,這就意味著不同組件之間的數(shù)據(jù)無法相互引用洪囤。所以如何傳遞數(shù)據(jù)也就成了組件需要解決的難題呵曹。
組件
1、父子組件
父子關(guān)系既是組件A在它的模版中使用了組件B,那么組件A就是父組件,組件B就是子組件。
// 注冊一個子組件
Vue.component('child', {
data: function(){
return {
text: '我是father的子組件彤断!'
}
},
template: '<span>{{ text }}</span>'
})
// 注冊一個父組件
Vue.component('father', {
template: '<div><child></child></div>' // 在模板中使用了child組件
})
在父組件中使用:
<div id="app">
<father></father>
</div>
頁面中就會渲染出 :我是father的子組件宰衙!
father 組件在模板中使用了 child 組件平道,所以它就是父組件,child 組件被使用供炼,所以 child 組件就是子組件一屋。
2窘疮、兄弟組件
Vue.component('brother1', {
template: '<div>我是大哥</div>'
})
Vue.component('brother2', {
template: '<div>我是小弟</div>'
})
使用:
<div id="app">
<brother1></brother1>
<brother2></brother2>
</div>
如何傳遞數(shù)據(jù)
在父組件 father.vue 中引用子組件 child.vue,把 name 的值傳給 child 組件陆淀。
<template>
<div class="app">
// message 定義在子組件的 props 中
<child :message="name"></child>
</div>
</template>
<script>
import child from './child.vue';
export default {
components: {
child
},
data() {
return {
name: 'linxin'
}
}
}
</script>
在子組件 child.vue 中的 props 選項中聲明它期待獲得的數(shù)據(jù)
<template>
<span>Hello {{message}}</span>
</template>
<script>
export default {
// 在 props 中聲明獲取父組件的數(shù)據(jù)通過 message 傳過來
props: ['message']
}
</script>
單向數(shù)據(jù)流
當父組件的 name 發(fā)生改變考余,子組件也會自動地更新視圖。但是在子組件中轧苫,我們不要去修改 prop楚堤。如果你必須要修改到這些數(shù)據(jù),你可以使用以下方法:
方法一:把 prop 賦值給一個局部變量含懊,然后需要修改的話就修改這個局部變量身冬,而不影響 prop
export default {
data(){
return {
newMessage: null
}
},
props: ['message'],
created(){
this.newMessage = this.message;
}
}
方法二:在計算屬性中對 prop 進行處理
export default {
props: ['message'],
computed: {
newMessage(){
return this.newMessage + ' 哈哈哈';
}
}
}
自定義事件
prop 是單向綁定的:當父組件的屬性變化時,將傳導(dǎo)給子組件岔乔,但是不會反過來酥筝。修改子組件的 prop 值,是不會傳回給父組件去更新視圖的雏门。那么子組件要如何去與父組件通訊呢嘿歌?
那就是自定義事件。通過在父組件 $on(eventName) 監(jiān)聽自定義事件茁影,當子組件里 $emit(eventName) 觸發(fā)該自定義事件的時候宙帝,父組件執(zhí)行相應(yīng)的操作。
比如在父組件中控制一個彈框子組件的顯示募闲,在子組件中按下關(guān)閉之后步脓,告訴父組件去隱藏它,然后父組件就執(zhí)行操作隱藏彈框浩螺。
<template>
<div class="app">
// hide 為自定義事件靴患,名字可以自己隨便起,不能有大寫字母要出,可以使用短橫線
// @hide 監(jiān)聽子組件觸發(fā) hide 事件鸳君,則會執(zhí)行 hideDialog 方法
<dialog :is-show="show" @hide="hideDialog"></dialog>
<button @click="showDialog">顯示彈框</button>
</div>
</template>
<script>
import dialog from './dialog.vue';
export default {
components: { dialog },
data() {
return {
show: false
}
},
methods: {
showDialog() {
this.show = true;
},
hideDialog() {
this.show = false;
}
}
}
</script>
在子組件 dialog.vue 中:
<template>
<div class="dialog" v-show="isShow">
<p>這里是彈框子組件</p>
<button @click="toHide">關(guān)閉彈框</button>
</div>
</template>
<script>
export default {
// 駝峰式命名的 prop 需要轉(zhuǎn)換為相對應(yīng)的短橫線隔開式 is-show
props: ['isShow'],
methods: {
toHide(){
// $emit 方法觸發(fā)父組件的監(jiān)聽事件
this.$emit('hide');
}
}
}
</script>
Event Bus
有時候兩個組件之間需要進行通信,但是它們彼此不是父子組件的關(guān)系厨幻。在一些簡單場景相嵌,你可以使用一個空的 Vue 實例作為一個事件總線中心(central event bus):
var bus = new Vue();
// 在組件 A 的 methods 方法中觸發(fā)事件
bus.$emit('say-hello', 'world')
// 在組件 B 的 created 鉤子函數(shù)中監(jiān)聽事件
bus.$on('say-hello', function (arg) {
console.log('hello ' + arg); // hello world
})
Vuex
在復(fù)雜場景中,你應(yīng)該考慮使用專門的狀態(tài)管理模式 Vuex况脆。
總結(jié)
組件通訊并不是一定要使用必須要使用 Vuex,對于一些簡單的數(shù)據(jù)傳遞批糟,event bus 或者 prop 也可以完成格了。本文主要是對組件傳參的一些基礎(chǔ)知識點的記錄。