【前端學習】Vue組件間通信問題

組件是一個完整獨立的,因此組件之間數據不會共享,想讓組件之間共享數據,我們要使用組件間通信的技術,組件間通信有兩個方向
父組件向子組件通信
子組件向父組件通信

·父組件向子組件通信

父組件向子組件通信分成兩步
第一步 爲子組件添加自定義屬性,並傳遞父組件中的數據
·屬性名稱:小寫字母,並且橫線分割單詞(不要以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;
		}
	}
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章