export default用法vue_Vue组件通信—provide/inject
前言:
之前在 Vue 中進行組件通信一般都會使用 props,開始使用 provide/inject 是非常偶然的一次嘗試。
當時在開發中需要實現祖孫組件,甚至祖祖祖祖孫組件之間的通信,在這種多層級場景下,props 就顯得太過累贅了,由于是進行設計器(插件)開發,為了提高插件的可復用性,減少不必要的包依賴,傾向于在不引入 Vuex 的情況下解決這個問題,那么就應該看看 vue 本身,是否具有這種能力,就在這個時候,我發現了 provide/inject。
官方定義
我們先來看看 Vue 官方的定義是什么:
provide/inject 是 Vue 在 2.2.0 版本新增的 API,官網這段定義看起來好像有點難理解,通俗的講,就是 provide 可以在祖先組件中指定我們想要提供給后代組件的數據或方法,而在任何后代組件中,我們都可以使用 inject 來接收 provide 提供的數據或方法。
舉個
// 父級組件提供 'foo' <template><div><div>{{foo}}</div><son></son></div> </template><script> import Son from "./Son"; export default {name: "parent",components: { Son },provide() {return {foo: this.foo};},data() {return {foo: "測試",};},mounted() {console.log(this.foo)}, }; </script>//子級組件,不接收 <template><grandSon></grandSon> </template><script> import grandSon from "./grandSon"; export default {name: "son",components: { grandSon }, }; </script>//孫級組件,接收foo <template><div>{{foo}}</div> </template><script> export default {name: "grandSon",inject: ["foo"],mounted() {console.log(this.foo)}, }; </script>在這里我們可以發現孫組件越過子組件接收了父組件注入的數據,我們可以理解為爺爺越過爸爸偷偷給孫子買了冰激凌,這是一組最簡單的用法,當層級繼續增加時,仍可通過這種方式由父組件直接跨域多個層級向后代組件注入數據。
有一點需要特別注意的是,實際上我們可以將當前組件inject獲取的數據直接賦值給它本身的data或props,不過官網提示我們,這是在Vue2.2.1版本才實現的功能,在這之前,必須先進行props和data數據的初始化。
響應更新
在嘗試中我們發現,由于Vue的單向流關系,實際上如果在parent中改變了初始傳入的foo的值以后,grandSon并不會得到改變后的值,也就是在這個時候,父孫組件的數據出現了不一致的情況,我們肯定是希望拿到的數據是一致的,怎么來解決這個問題呢,官網還有一句提示為我們提供了解釋。
提示:provide 和 inject 綁定并不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的對象,那么其對象的 property 還是可響應的。 也就是指,我們需要人為的將這組數據關系變成可響應的,哦,我們之前的foo是一個字符串,基本數據類型是不具有響應特性的,那么,我們可能需要傳遞一個對象。再舉個
// 改造一下父級組件提供 'foo' <template><div><div>{{foo}}</div><son></son></div> </template><script> import Son from "./Son"; export default {name: "parent",components: { Son },provide() {return {foo: this.foo};},data() {return {foo: {foo: "測試"},,};},mounted() {console.log(this.foo)}, }; </script>在這個栗子中,改造了一下父組件提供的數據,測試發現,foo變成了一組可響應的數據。經過嘗試我發現在這種情況下如果在孫組件改變inject中foo的值,也會響應的更新到父組件中,當然為了保護單向數據流機制,最佳實踐還是不要在子組件里更改inject(雖然 sync 也破壞了單向數據流)。
默認值設置
在 2.5.0+ 的注入可以通過設置默認值使其變成可選項<script> export default {name: "grandSon",inject: {foo: {from: 'bar',default: () => [1, 2, 3]}},mounted() {console.log(this.foo)}, }; </script>:在2.5.0 版本之后的版本中可以為inject提供默認值了,如果它需要從一個不同名字的 property 注入,則使用 from 來表示其源 property,與 prop 的默認值類似,需要對非原始值使用一個工廠方法。
呱唧呱唧,那基本用法我們就講到這里了,歸根結底,既然provide/inject 這么方便,為什么 Vue 官方還要推薦我們使用 Vuex進行數據管理呢?
明顯的缺點
provide/inject 的缺點還是非常明顯的:
- 當多個后代組件同時依賴同一個父組件提供數據時,只要任一組件對數據進行了修改,所有依賴的組件都會受到影響,實際上是增加了耦合度。
- 任意層級訪問使數據追蹤變的比較困難,你并不能準確的定位到是哪一個層級對數據進行了改變,當數據出現問題時,尤其是多人協作時,可能會大大增加問題定位的損耗。
值得肯定的優點
萬事萬物都有把雙刃劍,有缺點自然也有優點,在進行組件庫或高級插件開發時,provide/inject 仍然是一個不錯的選擇。
留坑待補(應當不會鴿)
- 從Vue生命周期源碼來看provide/inject的執行過程
- 插件/組件庫應用實例(同樣的功能實現與Vuex進行對比)
最后
其實之前的筆記都是寫給自己看的,這還是真正意義上的第一篇熱乎乎的博客,emmm感覺還有些地方沒有講的很明白,也還留坑了一些內容后續會慢慢完善,輸出真是不易的過程,不過會繼續努力學習提高噠,有問題歡迎指出,會及時更正,奧里給!
最后的最后
給我們的小組賣個安利,組內都是可愛的程序媛小姐姐哦,歡迎熱愛前端的小姐妹們加入我們,一起學習,共同進步【有意請留言或私信,社畜搬磚不及時,但看到會立刻回復】總結
以上是生活随笔為你收集整理的export default用法vue_Vue组件通信—provide/inject的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android蓝牙查看电池容量_双麦降噪
- 下一篇: codelite14中文语言包_Code