組件是一個完整獨立的,因此組件之間數據不會共享,想讓組件之間共享數據,我們要使用組件間通信的技術,組件間通信有兩個方向
父組件向子組件通信
子組件向父組件通信
·父組件向子組件通信
父組件向子組件通信分成兩步
第一步 爲子組件添加自定義屬性,並傳遞父組件中的數據
·屬性名稱:小寫字母,並且橫線分割單詞(不要以v-開頭)
·動態傳遞數據,可以使用v-bind指令
第二步 在子組件中接收傳遞的數據
通過props屬性接收數據,
是一個數組,每個成員代表一個數據,駝峯式命名
props屬性接收並註冊的數據,跟data屬性一樣,直接添加給組件實例化對象,並且設置了特性
我們可以在組件中訪問該數據
我們可以在模板中使用該數據
(第二種通信方式
我們可以通過在子組件中訪問$parent屬性,來訪問父組件實例化對象,並訪問父組件中的數據
工作中不建議使用,因爲與父組件耦合在一起。)
<!-- 1 傳遞屬性數據 -->
<Child :color="color" :parent-msg="msg"></Child>
// 定義子組件
var Child = Vue.extend({
// 2 子組件接收數據
props: ['color', 'parentMsg'],
template: `
<div>
<h2>child {{color}}-{{parentMsg}}</h2>
<!-- 不建議直接訪問父組件 -->
<h2>$parent {{$parent.color}}-{{$parent.msg}}</h2>
</div>
`,
// 構建完成
mounted() {
console.log(this)
console.log(this.$parent.msg, this.$parent.color)
}
})
// 定義vue實例化對象
new Vue({
el: '#app',
// 局部註冊
components: {
Child
},
data: {
msg: 'hello',
color: 'red'
},
})
·自定義事件
vue中實現了自定義事件,就是基於觀察者模式實現的。
vue繼承了觀察者模式的相關方法
//註冊消息方法
$on(type, fn)
type 表示消息類型
fn 表示回調函數
參數由$emit發佈消息的時候傳遞的
//發佈消息方法
$emit(type, ...args)
type 表示消息類型
args 發佈消息的時候,傳遞的數據
//註銷消息的方法
$off(type, fn)
type 表示消息類型
fn 表示回調函數
我們可以通過自定義事件實現父子組件之間的通信
注意:組件是完整獨立的,因此註冊的消息也不會共享(父組件註冊的消息,只能由父組件觸發,子組件不能觸發)
想實現子組件向父組件通信:
可以在父組件中註冊消息
子組件中,訪問$parent來發布消息
注意:由於在子組件中訪問了$parent,
因此與父組件耦合在一起了,因此工作中不建議。
·子組件向父組件通信
子組件向父組件通信是通過模擬DOM事件實現的。
定義DOM事件 @click=”fn”
模擬自定義事件 @ickt-demo=”fn”
首先在父組件模板中,爲子組件綁定自定義事件,此時事件回調函數要定義在父組件的methods中。
此時方法的this指向父組件,通過this修改數據,修改的是父組件中的數據
接着我們在子組件中,發佈通過$emit方法,發佈自定義自定義事件,並傳遞子組件中的數據。
此時執行父組件中的自定義事件的回調函數,並接收子組件傳遞的數據,並可以存儲在父組件中,
這樣就實現了子組件到父組件的通信
步驟
1 在父組件模板中,爲子組件綁定自定義事件
2 在父組件的methods中,定義事件回調函數
3 子組件中,通過$emti發佈自定義事件消息
4 父組件接收數據,並存儲在父組件中。
注意:定義自定義事件的時候,事件名稱橫線分割單詞,發佈事件的時候,事件名稱保持不變,也是橫線分割單詞。
<!-- 1 註冊自定義事件 -->
<Child @ickt-abc="receiveMessage"></Child>
// 定義子組件
var Child = Vue.extend({
template: `
<div>
<h2 @click="sendMessage">child</h2>
<input type="text" v-model="childMsg" />
</div>
`,
// 數據
data() {
return {
childMsg: ''
}
},
// 監聽數據的變化
watch: {
// 數據改變,要同步給父組件
childMsg(value, oldValue) {
// this.$emit('ickt-abc', this.childMsg)
this.$emit('ickt-abc', value)
}
},
// 方法
methods: {
// 3 發佈消息
sendMessage() {
this.$emit('ickt-abc', 500, true, 'abc')
}
}
})
// 定義vue實例化對象
new Vue({
el: '#app',
// 局部註冊
components: {
Child
},
data: {
msg: 'hello'
},
// 2 定義事件回調函數
methods: {
// 接收子組件數據的方法
receiveMessage(msg) {
// 4 接收數據並存儲
this.msg = msg;
}
}
})