在我日常的開發中,不少問題都是見招拆招,遇到了便去解決。久而久之,出現了一個大問題,就是會反覆的碰到這個問題,而反覆去解決,由於上次解決的方式不必定能記到。就像你看你幾個月前的代碼,都以爲:臥槽,誰的代碼,這麼爛。因此,最好的方式就是總結,不斷總結。vue
這張圖片就是
Vue
的簡便之處便在於組件,組件之間的複用讓Vue
項目維護起來十分簡便。而其中組件之間的通訊就是重中之重,無論哪個項目都有組件之間的通訊。而針對不一樣狀況下的組件之間通訊又各不相同,簡直五花八門。像最基礎的props
和@emit
父子組件通訊,大型項目官方推薦的Vuex
全局狀態管理,小型項目試用的Bus
通訊等等,接下來我就總結出幾種劍走偏鋒的幾種組件通訊。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