白話詳解Provide/Inject和Vuex的核心區別和使用場景

Lululala

May 23, 2021 Published

大部分人知道 Provide/Inject,但官方文件只寫著“建議做套件時使用”,網路上也很少找到相關文件和範例,殊不知你的專案裡面充滿許多合適使用場景,有時使用 Provide/Inject來取代或許會讓專案更好維護。

你的專案有以下場景卻還是使用Vuex的話,或許Provide/Inject可以幫助你提高專案品質

  1. 任何形式編輯器,可能是圖片、文字、網頁編輯器

  2. 一套資料管理方式,但會被重複使用在多個畫面

  3. 與全局資料無關、但又須被許多組建共用資料

  4. 表單步驟類型的組建(有很多上一步下一步的表單)

與Vuex核心的區別就是,Vuex的State管理是不能重複new的,但Provide/Inject可以

鬼才看得懂上面寫啥,來點Code詳解吧!

這裏用文章留言系統做範例,大部分人應該會選用Vuex則會長這樣,其他部分因文章篇幅省略

store/comments.js

如果今天多了個需求,同個畫面因使用者體驗優化會自動撈出適合的文章給使用繼續閱讀,變成留言系統不只一個,這時所有的留言不管是哪來的都變成在這集中管理,而這也正是噩夢的開始!

資料的集中使得管理變脆弱,造成未來許多問題,譬如:

  1. 假如像是Facebook的留言如果都集中在同個地方,會造成Array過大,可能造成記憶體浪費或效能問題

  2. 換頁之後多了User的Comments系統,就會有“要一起用store/comments.js嗎?”的疑慮

  3. User的Comments多了User才有的功能,邏輯要跟文章的混用寫在同個地方?

  4. 又多了專欄的留言,這時store/comments.js因邏輯不同容易變成God Object

如果改用Provide/Inject程式碼會變怎樣?

舉了一個簡單的例子,但為了盡量體現細節,所以打得程式碼有點多,總結的優點會整理在最下面

CommentProvider.vue

Comments.vue

CommentLike.vue

Post.vue

使用Provide/Inject的重點整理即好處

  1. CommentProvider是一個組件,可以被重複使用且有自己的資料管理data和Life Cycle,而不像Vuex的state無法重複利用

  2. 可利用組建天生的Life Cycle解決清除資料等等,Vuex需手動

  3. CommentProvider底下的Component都可以直接跟CommentProvider溝通避免用props傳遞

  4. 因CommentProvider的使用限制,只有該slot內的組件才能拿到$provider,未來很容易被抽離當組件

  5. Props都只需一個ID,和其他組件耦合度很低,變得改畫面時搬移組建會非常方便

  6. Props極少,變得組建邏輯的非常集中,相對好維護

Vuex和Provide/Inject的使用場景

  • Vuex比較偏向全局資料,像是登入者的資料和有無登入,資料無法確定未來哪些地方會被用到

  • Provide/Inject會像是組建類,明顯已知某些組建一定是相互共生,[Carousel, CarouselItem]、[Portal, PortalTarget]、[Table, TableColumn],element-ui這些組建不是用Provide/Inject寫的,這裡只是舉例

大家可能有的疑問?!

留言系統一樣可以用Vuex實現吧?是的,當然可以

Provide/Inject也只是個工具,滿多時候Vuex也都會是個好選擇,分享的目的也只是讓大家在開發複雜組建時,可以想到或許Provide/Inject是個不錯的選擇。

而我有個Side project是Sketch + Wix的結合體(可以讓設計師以同等Sketch的彈性做出線上RWD網頁) https://pagihub.com/ ,我自己在開發時覺得Provide/Inject比較容易管理超級複雜的樹狀資料。

如果有地方不懂的話在留言問問我囉~

最後!!!

這裡整合了真的程式編輯器(CodeMirror)和2000多種內遷服務來寫文章,有別於Medium和Markdown的體驗,更理所當然免錢,大家如果找不到適合的地方寫技術文,可以來試試 🥳

Vuex 資料管理