子組件多次複用且傳參到父組件時遇到的一些問題。

問題描述:

我們都知道,父子組件之間傳參用props,子向父用$emit,兄弟間有bus。但是今天遇到個問題,A組件是一個selector選擇器小組件,根據傳參不同選擇項目也不同,返回結果也不同。B組件中使用了4次A組件,傳參都不一樣,且需要將4次的返回結果都保存下來。
其實就是下圖4個自己封裝的選擇器,分別是A組件的4次複用,整個的大組件是B,B組件需要根據A組件的值來進行搜索,獲取統計等操作。手機號那裏是個input,很好獲取。
在這裏插入圖片描述

A組件選擇好值之後,將值保存在A組件的selectedData變量中。那麼B組件怎麼獲取到A組件中的值呢?

B組件獲取A組件中的值:

思路爲:
1.用Bus,當A組件完成選擇事件handleConfirm時,立即使用$emit方法,向B組件發送自定義方法selected,通知B組件已經完成選擇。B組件在mounted鉤子函數中,爲bus綁定$on事件,使用自定義方法selected,調用B組件中的處理函數selectorChang,selectorChang處理函數的作用是改變B組件中定義的一個變量selectorChangeFlag的布爾值,讓其取反。然後在watch監聽器中,監聽selectorChangeFlag的變化,這樣不論哪個A組件的值發生選擇變化,B組件都知道,且當selectorChangeFlag發生變化時,將4個A組件的值通過$refs來獲取到。

2.上面的思路饒了一個大圈子,既然在$on中就監聽到了變化,爲什麼不直接在此時將4個A組件的值通過$refs來獲取到。經測有效。開始想的時候還是想偏了。。。哭
簡化後流程爲:

用Bus,當A組件完成選擇事件handleConfirm時,立即使用$emit方法,向B組件發送自定義方法selected,通知B組件已經完成選擇。B組件在mounted鉤子函數中,爲bus綁定$on事件,使用自定義方法selected,在$on後面的回調函數中直接將4個A組件的值通過$refs來獲取到。或者通過給A組件綁定自定義屬性:data-value="selectedData"來獲取。

在這裏插入圖片描述
在這裏插入圖片描述

3.後來又想到,既然都已經用到bus了,爲什麼不直接在bus的$emit的時候將參數發過去呢?那樣就不用$refs或者data-*綁自定義屬性來獲取值了。
需要解決的一個問題就是B組件中要獲得4個值,而bus一次只傳遞了1個值,如果需要分別用$on綁定4次自定義事件selected,觸發的函數分別是getYear,getMonth,getType,getChannel,那樣會出問題。因爲每次完成選擇之後,year,month,type,channel的值都把之前的值覆蓋了!!
在這裏插入圖片描述
使用devtools查看vue中的值,確實是每次都覆蓋了。
在這裏插入圖片描述
所以我想要解決這個問題,只有在A組件中定義4個自定義方法,每個方法對應B組件中的一個方法,來獲取1個參數。
試試修改之後,發現還是不行!依然覆蓋前面的值。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
這裏我分析原因:
對於前面一種情況——每次A組件觸發emit事件,只能由這一個Bus來傳遞1個值,而B組件不知道A組件傳遞來的是year還是month或者其他,B只能被動的接收A組件傳遞過來的值!當B調用4個get函數來爲year,month賦值時,會將4個屬性都賦值了一遍!肯定覆蓋了前面的值!
對於後面一種情況——定義了4個自定義事件,相當於車上有4個座位!但是由於傳遞過來的仍然只有1個值,所以座位上的4個人都是同一個人!B組件接受A傳來的值時,依然將4個座位上的人分別賦值給4個屬性,但是這4個人根本就是同一個人!!所以依然覆蓋了前面的值!

想了很久,還是沒想出來如何只使用 Bus傳值 來獲取4個屬性,越想越亂,這個方法暫停一下吧。

4.這裏A,B其實是屬於父子組件關係,可以通過$emit直接傳值,而不需要使用bus。試了試發現,這樣實現也比較簡單。
A子組件直接觸發自定義事件並傳遞參數。

在這裏插入圖片描述
B組件直接在A組件上分別綁定自定義事件和處理函數!
在這裏插入圖片描述
檢查devtools,發現A組件值改變並不影響B組件中已經獲得的值!
在這裏插入圖片描述

分析原因:
我覺得這裏生成了4個A組件,然後在4個A組件上分別綁定各自的處理函數!每次A組件觸發$emit事件,B組件中的自定義事件selected調用對應的處理函數獲取這1個值,並不影響其他剩餘3個A組件的自定義事件selected!這裏很關鍵,它並不會影響其他3個A組件的selected事件。
這就相當於4臺車,一臺車一次只拉1個人,拉回來之後只觸發1個處理函數,並且通過處理函數來賦值。其他的車一樣處理,每臺車之間互不影響!
而互不影響的原因是,4個A組件之間雖然有同樣的自定義函數名selected,但是因爲分別屬於4個實例,year這個A組件中的selected不會觸發綁定在month這個A組件上的處理函數getMonth!作用域不同!
這樣就不會覆蓋其他的3個值!

目前我的的最佳解決方式就是:

二、使用bus或者$emit觸發子組件的處理事件,然後通知B組件通過$ref或者自定義屬性獲取值。
1.A子組件中bus.$emit發送自定義方法,告知B組件。
2.B父組件中bus.$on監聽到後,直接在回調函數中,通過$refs獲取所有A組件中的屬性(對於沒有發送選擇的獲取到的值爲空,有空值處理)。

四、直接使用子傳父$emit並且傳值。
1.A子組件中this.$emit發送自定義方法selected,告知B組件,並將值傳遞過去。
2.B組件在複用的A組件上面綁定自定義方法,並且調用對應的處理函數來賦值。

關於如何只使用bus並且傳參的方法是否能行,暫時沒想到,不知道有沒有大佬告知一下。暫時就這樣吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章