在我平常的開發中,很多問題都是見招拆招,遇到了便去解決。長此以往,出現了一個大問題,就是會反覆的碰到這個問題,而反覆去解決,因為上次解決的方式不一定能記到。就像你看你幾個月前的程式碼,都覺得:臥槽,誰的程式碼,這麼爛。所以,最好的方式就是總結,不斷總結。
這張圖片就是
Vue
的簡便之處便在於元件,元件之間的複用讓Vue
專案維護起來十分簡便。而其中元件之間的通訊就是重中之重,不管哪一個專案都有元件之間的通訊。而針對不同情況下的元件之間通訊又各不相同,簡直五花八門。像最基礎的props
和@emit
父子元件通訊,大型專案官方推薦的Vuex
全域性狀態管理,小型專案試用的Bus
通訊等等,接下來我就總結出幾種劍走偏鋒的幾種元件通訊。
Vue
官方api 中的,通過$parent
和$children
就可以訪問元件的例項,拿到例項代表什麼?代表可以訪問此元件的一切方法和data
。雖然官方說節制的使用,但是我還是選擇了無視。接下來就該思考下怎麼去拿到指定元件的例項。
這應該是個通用的方法,原理就是通過不斷遍歷找到符合標準的元件例項,通過拿到的元件例項來拿到該例項的方法和data
要注意邊界情況,如在
#app
上拿$parent
得到的是new Vue()
的例項,在這例項上再拿$parent
得到的是undefined
,而在最底層的子元件拿$children
是個空陣列。也要注意得到$parent
和$children
的值不一樣,$children
的值是陣列,而$parent
是個物件
/**
* @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
和方法。
使用此方法需要注意幾點
一、第一個引數必須是['$parent', '$children']
中的一種,否則返回undefined
二、該方法必須在mounted
生命週期中使用,不然程式碼中的currentComponent.length
的值是0,(別問我為什麼,我也不知道為什麼)
然後就可以通過此方法得到你指定的元件例項,當然你可能會問,有Vuex
等其他的通訊方法,為什麼要使用這個方法,或者說在什麼情況下合適使用該方法。如果你自己寫了一個自定義通用元件,現在你的組員想用這個元件,但是你把控制元件狀態的值都寫在了Vuex
上了,這時候就麻煩了。這時候使用這個方法應該說比較好,不需要其他的外部依賴,即拿即用。
最後說一句,該方法出自iview
原始碼中的尋找元件方法,我只是將其稍微改造了下,你可以點此連結檢視iview
原始碼。