Vue 依賴注入 - Provide/Inject

官網(wǎng)傳送門:inject ?Vue2.2.0+

# 背景

? 關于Vue組件的通訊方式相信大家能倒背如流

  • 父子組件:通過prop,$emit,【$root,$parent,$children
  • 非父子組件:Vuex實現(xiàn),父子層層傳遞、中央事務總線Bus,$ref

子實例可以用 this.$parent 訪問父實例,子實例被推入父實例的 $children 數(shù)組中。應當節(jié)制地使用它們,其只是作為訪問組件的應急方法。更推薦用 props 和 events 實現(xiàn)父子組件通信.

Vue官網(wǎng)建議,在正常情況下,這兩種方式已經(jīng)能滿足絕大多數(shù)甚至所有的業(yè)務需求,對于應用程序代碼應優(yōu)先使用它們處理。然而,還有一種主要為高階插件/組件庫提供的用例辦法,即provide/inject,這對選項需要一起使用。
?

# 功能

? 通常情況下,組件向組件傳遞數(shù)據(jù),可以采用父子props層層傳遞,也可以使用busVuex直接交互。在Vue2.2.0之后,Vue還提供了provide/inject選項

這對選項允許一個祖先組件向其所有子孫后代組件注入一個依賴,不論組件層次有多深,并在起上下游關系成立的時間里始終生效。

? 也就是說,在父組件只要聲明了provide,在其子組件,孫組件,曾孫組件等能形成上下游關系的組件中交互,無論多深都能通過inject來訪問provider中的數(shù)據(jù)。而不是局限于只能從當前父組件的prop屬性來獲取。注意他只做祖先通后代的單向傳遞的一個辦法。有人這么形容:

provide就相當于加強版父組件prop,可以跨越中間組件inject就相當于加強版子組件的props
?

# 缺點

? 官網(wǎng)不建議在應用中直接使用該辦法,理由很直接:他怕你"管不好"

? 設計項目,通常追求有清晰的數(shù)據(jù)流向和合理的組件層級關系便于調試和維護,然而這對選項支持任意層級都能訪問,導致數(shù)據(jù)追蹤比較困難。不知道那一層級聲明了provide又或是哪些層級使用了inject。造成比較大的維護成本。因此,除組件庫或高階插件外,Vue建議用Vuex解決或其他辦法處理。
?

# 使用辦法

  • provide 提供變量:Object | () => Object
  • inject 注入變量: Array<string> | { [key: string]: string | Symbol | Object }

? provide 選項應該是一個對象或返回一個對象的函數(shù)。 該對象包含可注入其子孫的屬性。在該對象中,它支持ES6中Symbol作為key,但只在原生支持等環(huán)境下可工作。

? inject 選項可以是

  • 一個字符串數(shù)組
  • 一個對象,key為本地綁定名,value為:
    • 在可用的注入內容中搜索用的key,或
    • 一個對象,其 from 屬性是在可用的注入內容中搜索用的keydefault屬性是降級情況下使用的value

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

?

# 案例展示

在父組件中provide提供變量

<template>
  <div>
    <p>{{ title }}</p>
    <son></son>
  </div>
</template>
<script>
  import Son from "./son"
  export default {
    name: 'Father',
    components: { Son },
    // provide選項提供變量
    provide: {
      message: 'provided by father'
    },
    data () {
      return {
        title: '父組件'
      }
    },
    methods: { ... }
  }
</script>

在子組件中,我們故意不使用任何父組件的信息

<template>
  <div>
    <p>{{ title }}</p>
    <grand-son></grand-son>
  </div>
</template>
<script>
import grandSon from "./grandSon "
export default {
  name: "Son",
  components: { grandSon },
  data () {
    return {
      title: '子組件'
    }
  },
};
</script>

在孫組件中,使用inject來注入

<template>
  <div>
    <p>message:{{ message }}</p>
  </div>
</template>
<script>
export default {
  name: "GrandSon",
  inject: [ "message" ],
  data () {
    return {
      title: '孫組件'
    }
  },
  methods: { ... }
};
</script>

結果孫組件頁面顯示:
message: provided by father
?

建議

使用依賴注入時,強烈建議使用命名空間策略,根據(jù)父組件特性對命名空間名稱做規(guī)范,可以解決不知道哪里提供的問題。且依賴注入是單向數(shù)據(jù)流,有統(tǒng)一分發(fā)數(shù)據(jù)的優(yōu)勢,合理使用能提供很大便利性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容