劍走偏鋒之Vue 組件通訊(一)—經過$parent和$children構建本身的通信方式

在我日常的開發中,不少問題都是見招拆招,遇到了便去解決。久而久之,出現了一個大問題,就是會反覆的碰到這個問題,而反覆去解決,由於上次解決的方式不必定能記到。就像你看你幾個月前的代碼,都以爲:臥槽,誰的代碼,這麼爛。因此,最好的方式就是總結,不斷總結。vue

Vue 的簡便之處便在於組件,組件之間的複用讓Vue項目維護起來十分簡便。而其中組件之間的通訊就是重中之重,無論哪個項目都有組件之間的通訊。而針對不一樣狀況下的組件之間通訊又各不相同,簡直五花八門。像最基礎的props@emit 父子組件通訊,大型項目官方推薦的Vuex全局狀態管理,小型項目試用的Bus通訊等等,接下來我就總結出幾種劍走偏鋒的幾種組件通訊。api

vue 官方api
這張圖片就是 Vue 官方 api 中的,經過 $parent$children就能夠訪問組件的實例,拿到實例表明什麼?表明能夠訪問此組件的一切方法和 data。雖然官方說節制的使用,可是我仍是選擇了無視。接下來就該思考下怎麼去拿到指定組件的實例。

這應該是個通用的方法,原理就是經過不斷遍歷找到符合標準的組件實例,經過拿到的組件實例來拿到該實例的方法和data數組

要注意邊界狀況,如在#app上拿$parent獲得的是new Vue()的實例,在這實例上再拿$parent獲得的是undefined,而在最底層的子組件拿$children是個空數組。也要注意獲得$parent$children的值不同,$children 的值是數組,而$parent是個對象bash

/**
* @desc 尋找指定組件實例
* @params {String} type 向上查找仍是向下查找
* @params {Object} context 當前上下文(通常指this,把this 傳進來就能夠了)
* @params {String} componentName 要尋找的指定的組件名
*/
function findComponents (type, context, componentName) {
	if (['$parent', '$children'].indexOf(type) < 0) return

	let currentComponent = context[type]
	if (type === '$parent') currentComponent = [currentComponent]
	let designatedCom = null

	if (currentComponent.length) {
		for(const com of currentComponent) {
			const name = com.$options.name

			if (name === componentName) {
				designatedCom = com
				break
			} else {
				designatedCom = findComponents(type, com, componentName)
				if (designatedCom) break
			}
		}
		return designatedCom
	}
複製代碼

這個方法能夠向上向下尋找跨組件的子,父組件的實例,拿到實例後就能夠拿到相應的data和方法。app

使用此方法須要注意幾點
1、第一個參數必須是['$parent', '$children']中的一種,不然返回undefined
2、該方法必須在mounted生命週期中使用,否則代碼中的currentComponent.length的值是0,(別問我爲何,我也不知道爲何)iview

而後就能夠經過此方法獲得你指定的組件實例,固然你可能會問,有Vuex等其餘的通訊方法,爲何要使用這個方法,或者說在什麼狀況下合適使用該方法。若是你本身寫了一個自定義通用組件,如今你的組員想用這個組件,可是你把控制組件狀態的值都寫在了Vuex上了,這時候就麻煩了。這時候使用這個方法應該說比較好,不須要其餘的外部依賴,即拿即用。 最後說一句,該方法出自iview源碼中的尋找組件方法,我只是將其稍微改造了下,你能夠點此連接查看iview源碼。ui

相關文章
相關標籤/搜索