Hi,大家好,我是小馬彬,前兩篇展示了子組件如何有效的將資料更新回父組件,如果還沒看過各種不同的父子組件溝通的方式,可以先看看上一篇『Vue 子組件更新父組件資料的『五種』方式(Part 2)』,這篇要來介紹 provide / inject,它主要的功能就是能讓跨組件的資料傳遞更為方便
如果子組件想要得到父組件的資料,就得用 props 來接,那如果得跨越很多層才到目標的組件,那中間每一層組件都得寫上 props 的程式碼來向下傳,有時候就會覺得中間的組件明明沒用到,程式碼已經一大堆,卻又要每一個都多補上這一段實在很不划算
一般 props 的方式向子組件傳遞資料
那麼今天曾祖父組件的資料,要讓子組件來使用呢?
曾祖父 -> 祖父 -> 父 -> 子
假使 Vue 專案為以下的結構
1 | app |
曾祖父組件準備了資料 list,而後交給了祖父組件
Page.vue
祖父組件拿到了 list 資料,再轉交給父組件
Page.vue
↓
ListContainer.vue
父組件拿到了 list 資料,最後的轉交給了子組件
Page.vue
↓
ListContainer.vue
↓
ListSection.vue
子組件終於得到了 list,可以來把資料列舉出來
Page.vue
↓
ListContainer.vue
↓
ListSection.vue
↓
List.vue
曾祖父所傳達的東西意境深遠,看來是想要告訴我要享受當下,亦或是我們家族有個仇人叫東東?
用 provide / inject 來向子組件傳遞資料
回到 Vue,現在筆者不想要經過這麼多組件才能得到 list,這時就能用上 provide / inject 的方式來傳遞
專案結構與剛剛一樣
1 | app |
Page.vue
將 this.list 裝到 provide()
中
這樣資料就能讓子組件輕鬆的拿到
以下 ListContainer.vue 及 ListSection.vue 就沒有寫任何 props
ListContainer.vue
ListSection.vue
最後 List.vue 直接 inject
list 進來就能直接使用囉
List.vue
最後的畫面跟剛剛的一樣
只要在較上層的組件中用 provide() 裝資料,這樣不管經過了幾代的子組件,都能直接用 inject,就能將上層組件的 provide() 提供的資料拿到手
這邊要注意的是,這種傳資料方式,就沒有強制型別的宣告了,所以使用上要特別小心,筆者其實也很少用到,是剛好有次因為組件都已經分散得七零八落,需要傳遞很多層才到子組件,就要多寫很多 props 的程式碼,就偷懶用了這個 XD
總結
筆者認為一定要非常確定這個資料僅僅是在這個 page 中獨立使用(或是一個完全獨立可拆分的複雜組件),才適合 provide / inject,如果胡亂使用反而可能會造成維護較困難的情況,或是使用的目的會被混淆,不過當然可以透過變數命名改善 XD,如果是更多更多 page 要共用數據,還是會比較建議用 Vuex,在撰寫跟後續維護上會比較容易得到可預期的結果