最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

聊聊Vue中provide/inject的應用詳解

 更新時間:2019年11月10日 14:22:19   作者:格子熊  
這篇文章主要介紹了聊聊Vue中provide/inject的應用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

眾所周知,在組件式開發(fā)中,最大的痛點就在于組件之間的通信。在 Vue 中,Vue 提供了各種各樣的組件通信方式,從基礎的 props/$emit 到用于兄弟組件通信的 EventBus,再到用于全局數(shù)據(jù)管理的 Vuex。

在這么多的組件通信方式中,provide/inject 顯得十分阿卡林(毫無存在感)。但是,其實 provide/inject 也有它們的用武之地。今天,我們就來聊聊 Vue 中 provide/inject 的應用。

何為 provide/inject

provide/inject 是 Vue 在 2.2.0 版本新增的 API,官網(wǎng)介紹如下:

這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時間里始終生效。如果你熟悉 React,這與 React 的上下文特性很相似。

官網(wǎng)的解釋很讓人疑惑,那我翻譯下這幾句話:

provide 可以在祖先組件中指定我們想要提供給后代組件的數(shù)據(jù)或方法,而在任何后代組件中,我們都可以使用 inject 來接收 provide 提供的數(shù)據(jù)或方法。

舉個官網(wǎng)的🌰:

// 父級組件提供 'foo'
var Provider = {
 provide: {
  foo: 'bar'
 },
 // ...
}

// 子組件注入 'foo'
var Child = {
 inject: ['foo'],
 created () {
  console.log(this.foo) // => "bar"
 }
 // ...
}

可以看到,父組件提供的 foo 變量被子組件成功接收并使用。

了解了 provide/inject 是什么后,我們再來使用使用 provide/inject。

使用 provide/inject 做全局狀態(tài)管理

在日常開發(fā)中,我們經(jīng)常會使用 Vuex 做狀態(tài)管理,但是,我個人一直不喜歡使用 Vuex,原因在于 Vuex 為了保持狀態(tài)可被回溯追蹤,使用起來太過繁瑣;而我之前參與的項目,較少多人合作,這個功能對于我來說,意義不大,我僅僅只需要 Vuex 中提供全局狀態(tài)的功能。

那么,有沒有方便快捷的實現(xiàn)全局狀態(tài)的方法呢?當然有,這就是 provide/inject 這個黑科技 API 的一種使用方法。

很多人也許會想到一種方式:在根組件中,傳入變量,然后在后代組件中使用即可。

// 根組件提供一個非響應式變量給后代組件
export default {
 provide () {
  return {
   text: 'bar'
  }
 }
}

// 后代組件注入 'app'
<template>
 <div>{{this.text}}</div>
</template>
<script>
 export default {
  inject: ['text'],
  created() {
   this.text = 'baz' // 在模板中,依然顯示 'bar'
  }
 }
</script>

這個想法,說對也對,說不對也不對,原因在于 provide 的特殊性。

在官網(wǎng)文檔中關(guān)于 provide/inject 有這么一個提示:

提示:provide 和 inject 綁定并不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監(jiān)聽的對象,那么其對象的屬性還是可響應的。

也就是說,Vue 不會對 provide 中的變量進行響應式處理。所以,要想 inject 接受的變量是響應式的,provide 提供的變量本身就需要是響應式的。

由于組件內(nèi)部的各種狀態(tài)就是可響應的,所以我們直接在根組件中將組件本身注入 provide,此時,我們可以在后代組件中任意訪問根組件中的所有狀態(tài),根組件就成為了全局狀態(tài)的容器,仔細想想,是不是很像 React 中的 context 呢?

代碼如下:

// 根組件提供將自身提供給后代組件
export default {
 provide () {
  return {
   app: this
  }
 },
 data () {
  return {
   text: 'bar'
  }
 }
}

// 后代組件注入 'app'
<template>
 <div>{{this.app.text}}</div>
</template>
<script>
 export default {
  inject: ['app'],
  created() {
   this.app.text = 'baz' // 在模板中,顯示 'baz'
  }
 }
</script> 

也許有的同學會問:使用 $root 依然能夠取到根節(jié)點,那么我們何必使用 provide/inject 呢?

在實際開發(fā)中,一個項目常常有多人開發(fā),每個人有可能需要不同的全局變量,如果所有人的全局變量都統(tǒng)一定義在根組件,

勢必會引起變量沖突等問題。
使用 provide/inject 不同模塊的入口組件傳給各自的后代組件可以完美的解決該問題。

慎用 provide/inject

既然 provide/inject 如此好用,那么,為什么 Vue 官方還要推薦我們使用 Vuex,而不是用原生的 API 呢?

我在前面提到過,Vuex 和 provide/inject 最大的區(qū)別在于,Vuex 中的全局狀態(tài)的每次修改是可以追蹤回溯的,而 provide/inject 中變量的修改是無法控制的,換句話說,你不知道是哪個組件修改了這個全局狀態(tài)。

Vue 的設計理念借鑒了 React 中的單向數(shù)據(jù)流原則(雖然有 sync 這種破壞單向數(shù)據(jù)流的家伙),而 provide/inject 明顯破壞了單向數(shù)據(jù)流原則。試想,如果有多個后代組件同時依賴于一個祖先組件提供的狀態(tài),那么只要有一個組件修改了該狀態(tài),那么所有組件都會受到影響。這一方面增加了耦合度,另一方面,使得數(shù)據(jù)變化不可控。如果在多人協(xié)作開發(fā)中,這將成為一個噩夢。

在這里,我總結(jié)了兩條條使用 provide/inject 做全局狀態(tài)管理的原則:

  • 多人協(xié)作時,做好作用域隔離
  • 盡量使用一次性數(shù)據(jù)作為全局狀態(tài)

看起來,使用 provide/inject 做全局狀態(tài)管理好像很危險,那么有沒有 provide/inject 更好的使用方式呢?當然有,那就是使用 provide/inject 編寫組件。

使用 provide/inject 編寫組件

使用 provide/inject 做組件開發(fā),是 Vue 官方文檔中提倡的一種做法。

以我比較熟悉的 elementUI 來舉例:

在 elementUI 中有 Button(按鈕)組件,當在 Form(表單)組件中使用時,它的尺寸會同時受到外層的 FormItem 組件以及更外層的 Form 組件中的 size 屬性的影響。

如果是常規(guī)方案,我們可以通過 props 從 Form 開始,一層層往下傳遞屬性值??雌饋碇恍枰獋鬟f傳遞兩層即可,還可以接受。但是,F(xiàn)orm 的下一層組件不一定是 FormItem,F(xiàn)ormItem 的下一層組件不一定是 Button,它們之間還可以嵌套其他組件,也就是說,層級關(guān)系不確定。如果使用 props,我們寫的組件會出現(xiàn)強耦合的情況。

provide/inject 可以完美的解決這個問題,只需要向后代注入組件本身(上下文),后代組件中可以無視層級任意訪問祖先組件中的狀態(tài)。

部分源碼如下:

// Button 組件核心源碼
export default {
  name: 'ElButton',
  // 通過 inject 獲取 elForm 以及 elFormItem 這兩個組件
  inject: {
    elForm: {
      default: ''
    },
    elFormItem: {
      default: ''
    }
  },
  // ...
  computed: {
    _elFormItemSize() {
      return (this.elFormItem || {}).elFormItemSize;
    },
    buttonSize() {
      return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
    },
    //...
  },
  // ...
};

總結(jié)

其實在 Vue 的學習中,遵循著二八法則,我們常用的 20% 的 API 就能解決大部分日常問題,剩余的 API 感覺用處不大。但是,抽點時間去了解那些冷門的 API,也許你能發(fā)現(xiàn)一些不一般的風景,令你在解決一些問題時,事半功倍。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue中路由傳參的實用方式?分享

    Vue中路由傳參的實用方式?分享

    這篇文章主要為大家詳細介紹了VUE項目中路由之間的傳值方式,文中的示例代碼講解詳細,涉及到的方法也都是開發(fā)時常用的,希望對大家有多幫助
    2023-06-06
  • 初識簡單卻不失優(yōu)雅的Vue.js

    初識簡單卻不失優(yōu)雅的Vue.js

    這篇文章主要為大家介紹了簡單卻不失優(yōu)雅、小巧而不乏大匠的Vue.js,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局

    Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局

    這篇文章主要介紹了Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局,工作中難免遇到需要對頁面布局進行拖拽然后改變布局,保存布局,下面文章就圍繞Vue3.0利用vue-grid-layout插件實現(xiàn)拖拽布局的相關(guān)資料展開詳細內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • vue uniapp實現(xiàn)分段器效果

    vue uniapp實現(xiàn)分段器效果

    這篇文章主要為大家詳細介紹了vue uniapp實現(xiàn)分段器效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • vue獲取或者改變vuex中的值方式

    vue獲取或者改變vuex中的值方式

    這篇文章主要介紹了vue獲取或者改變vuex中的值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Nuxt 嵌套路由nuxt-child組件用法(父子頁面組件的傳值)

    Nuxt 嵌套路由nuxt-child組件用法(父子頁面組件的傳值)

    這篇文章主要介紹了Nuxt 嵌套路由nuxt-child組件用法(父子頁面組件的傳值),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 當啟動vue項目安裝依賴時報錯的解決方案

    當啟動vue項目安裝依賴時報錯的解決方案

    這篇文章主要介紹了當啟動vue項目安裝依賴時報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue 導航內(nèi)容設置選中狀態(tài)樣式的例子

    vue 導航內(nèi)容設置選中狀態(tài)樣式的例子

    今天小編就為大家分享一篇vue 導航內(nèi)容設置選中狀態(tài)樣式的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • vue移動端的左右滑動事件詳解

    vue移動端的左右滑動事件詳解

    這篇文章主要為大家詳細介紹了vue移動端的左右滑動事件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • 強大Vue.js組件淺析

    強大Vue.js組件淺析

    這篇文章主要為大家介紹了Vue.js組件,組件是Vue.js最強大的功能之一,感興趣的小伙伴們可以參考一下
    2016-09-09

最新評論

甘德县| 资中县| 工布江达县| 炎陵县| 仙居县| 安泽县| 卓尼县| 芦溪县| 河南省| 金华市| 张掖市| 淳安县| 亚东县| 鄂托克旗| 定州市| 虹口区| 平山县| 砀山县| 景洪市| 双城市| 高台县| 且末县| 郑州市| 泰安市| 平遥县| 来凤县| 盐山县| 沙洋县| 昌邑市| 伊金霍洛旗| 德阳市| 安丘市| 大埔区| 延寿县| 攀枝花市| 铜梁县| 富锦市| 治多县| 云梦县| 日土县| 漳浦县|