avatar

目錄
Vue 子組件更新父組件資料 - 特別篇,provide / inject

Hi,大家好,我是小馬彬,前兩篇展示了子組件如何有效的將資料更新回父組件,如果還沒看過各種不同的父子組件溝通的方式,可以先看看上一篇『Vue 子組件更新父組件資料的『五種』方式(Part 2)』,這篇要來介紹 provide / inject,它主要的功能就是能讓跨組件的資料傳遞更為方便

如果子組件想要得到父組件的資料,就得用 props 來接,那如果得跨越很多層才到目標的組件,那中間每一層組件都得寫上 props 的程式碼來向下傳,有時候就會覺得中間的組件明明沒用到,程式碼已經一大堆,卻又要每一個都多補上這一段實在很不划算

一般 props 的方式向子組件傳遞資料

那麼今天曾祖父組件的資料,要讓子組件來使用呢?

曾祖父 -> 祖父 -> 父 -> 子

假使 Vue 專案為以下的結構

plaintext
1
2
3
4
5
6
7
8
app
├── pages
│ └── Page.vue (曾祖父)
├── components
│ ├── ListContainer.vue (祖父)
│ ├── ListSection.vue (父)
│ └── List.vue (子)
└── App.vue

曾祖父組件準備了資料 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 的方式來傳遞

專案結構與剛剛一樣

plaintext
1
2
3
4
5
6
7
8
app
├── pages
│ └── Page.vue
├── components
│ ├── ListContainer.vue
│ ├── ListSection.vue
│ └── List.vue
└── App.vue

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,在撰寫跟後續維護上會比較容易得到可預期的結果

文章作者: 小馬彬
文章鏈接: https://littlehorseboy.github.io/2020/02/16/2020-vue-component-provide-inject/
版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 小馬彬的部落格

評論