vue組件中的通訊方式

前言

在vue中,組件間的通訊方式尤其重要。首先,咱們來講如下 組件間的關係有哪些呢?父子組件,兄弟組件以及隔代組件。關於父子組件中通訊方式,最經常使用的就是props,$emit,兄弟組件間的通訊方式有eventBus,vuex等方式。然而 ,忽然發現還有好幾種組件通訊的方式未被開啓。因此,在這裏,總結一下vue中的組件通訊方式有哪些,每種方式 又都有什麼奧妙的地方。vue

1.props和$emit

其實,這種方式是咱們在vue中常用的,對於它的用法就在這裏不一一細說了。只說一下關於它的使用的注意事項。
首先,說一下,在父子組件間的通訊,數據的流向是單向數據流的。
全部的prop都使用的其父子prop之間造成一個單向下行綁定:父級prop的更新會向下流動到子組件中,可是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態,從而致使你的應用的數據流難以理解。
額外的,每次父級組件發生更新時,子組件中全部的prop都將會刷新爲最新的值。這意味着你不該該在一個子組件內部改變你prop。若是你這樣子作了,vue會在瀏覽器的控制檯中發出警告。 ---vue官方文檔。
昨天,看一位同事的代碼,忽然發現了一個很吊的操做,不是在組件中對父組件中傳過來的props(好比:字符串,數值類型)直接修改會提示錯誤信息嗎?可是對於父組件中傳過來的props(對象),修改其中的某一個屬性是不會報錯的。因此,利用這一點,在子組件中傳入對象的類型,而後修改其中某一個屬性。其實,這種操做雖然沒有報錯,可是其實,在改變子組件中的同時,也改變了父組件中的數據。這種方案仍是不可取的。
子組件:在子組件中更改父組件的數據,vuex

clipboard.png
父組件:在父組件監聽一下 ,在子組件更改父組件中的數據的時候,父組件中的這個數據是否發生變化。
clipboard.png
那有沒有什麼解決方案呢?數組

1.在子組件中定義一個數據,去接收傳過來的數據.

clipboard.png

2.若是傳入到子組件的數據須要轉換的話,可使用計算屬性來實現。
3.v-model的使用方式
在父組件中,子組件綁定v-model:
![clipboard.png](/img/bVbw4QI)
在子組件中,除了要在props中聲明以外,還須要再model中進行聲明:
![clipboard.png](/img/bVbw4QR)

2.vuex

咱們在學習vue的同時,也基本會學習使用vuex,vuex是一個數據狀態管理器,而放在store中的數據,是全局狀態的,正是由於這個特性,咱們可使用vuex進行兄弟組件間的傳值。關於vuex的使用,你們能夠看官網學習一下:https://vuex.vuejs.org/zh/guide/瀏覽器

3.$parent,$children

$parent:指定已建立的實例之父的實例,在二者之間創建了父子關係。子實例能夠經過this.$parent訪問實例,子實例被推入父實例的$children中。
例如:在子組件中打印this.$parent的結果是一個對象,裏面是父組件的信息:dom

clipboard.png
$children:當前實例的子組件。例如:在父組件中打印this.$children能夠獲取到一個數組,這個數組裏麪包含其全部的子組件。ide

clipboard.png

4.$listeners $attrs:

適用於隔代組件,且中間組件只是爲了數據的傳遞。例如:A組件包含B組件,B組件包含C組件。須要將A組件中的message這個數據傳到C組件中。常見的寫法,就是咱們先將A組件中的message數據傳遞到B組件中,而後再由B組件傳遞到C組件。而後,在這裏,介紹一種新的寫法:#attrs,$listenters.
$attrs包含了父做用域中不做爲prop被識別(且獲取)的特性綁定(class和style除外)。當一個組件沒有聲明任何prop時,這裏會包含全部父做用域的綁定(class和style除外),而且能夠經過v-bind="$attrs"傳入內部組件--在建立高級別的組件時很是有用。
emmm...上面這句話,讀着挺繞口的,就是簡單來講,將父組件中傳入的數據到子組件,而後子組件中沒有使用prop接收的數據都存放在$attrs中,若是想把$attrs中的數據傳到內部子組件,就能夠直接在子組件上v-bind="$attrs"上傳入到內部子組件。函數

A組件(傳入text1,text2到B組件):學習

clipboard.png

B組件(只接受了text1,沒有接收text2,使用$attrs將text2傳到C組件):ui

clipboard.png

C組件(接收text2):this

clipboard.png

結果展現:

clipboard.png

上面這個簡單的例子,就詳情的介紹了一下$attrs的使用,這種方式的使用對於隔代組件通訊的使用,自我感受是很方便的。

$listeners:包含了父做用域中的(不含.native修飾器)v-on事件監聽器,它能夠經過v-on=$listeners 傳入內部組件--在建立更高層次的組件時sh很是有用的。
這個屬性就是和$attrs時相似的,只不過是自定義事件從子組件傳到父組件的使用。

clipboard.png

5.Provide inject的使用(主要爲高階插件/組件庫提供用例。)

provide選項是一個對象或者返回一個對象的函數。該對象包含可注入其子孫的屬性。
inject選項應該是一個字符串數組或者是一個對象。
這對選項須要一塊兒使用,以容許一個組件組件向其全部子孫後代注入一個依賴,不論組件層次有多深,而且在起上下游關係成立的時間裏始終生效。
代碼的使用以下圖:
clipboard.png

6.EventBus:組件間的通訊

EventBus 又稱爲事件總線。在Vue中可使用 EventBus 來做爲溝通橋樑的概念,就像是全部組件共用相同的事件中心,能夠向該中心註冊發送事件或接收事件,因此組件均可以上下平行地通知其餘組件,但也就是太方便因此若使用不慎,就會形成難以維護的災難,所以才須要更完善的Vuex做爲狀態管理中心,將通知的概念上升到共享狀態層次。

7.this.$refs使用

ref:被用來給元素或子組件註冊引用信息,引用信息將會註冊在父組件的#refs對象上。
能夠經過$refs拿到對應組件中想要獲取的數據,可是,不建議使用,只有沒得辦法的時候,在使用。例如,須要操做dom節點的時候,或者在組件中,沒法經過點擊事件獲取數據的時候,可使用this.$refs

clipboard.png
clipboard.png

總結

以上就是針對vue中組件的通訊方式的瞭解,每種通訊方式都有本身的利與弊,咱們能夠根據項目的實際需求去選擇適合的通訊方式,切記,濫用。而後哪裏寫的不對,請多多指教。由於有些方法本身在項目中使用的場景也比較少見,可能會存在誤差,歡迎指出問題!!!

相關文章
相關標籤/搜索