淺談vue中provide和inject 用法

前端嵐楓發表於2019-03-25

provide:Object | () => Object inject:Array | { [key: string]: string | Symbol | Object } provide 和 inject 主要為高階外掛/元件庫提供用例。並不推薦直接用於應用程式程式碼中。是2.2.0版本 新增的。 這對選項需要一起使用,以允許一個祖先元件向其所有子孫後代注入一個依賴,不論元件層次有多深,並在起上下游關係成立的時間裡始終生效。

provide 選項應該是一個物件或返回一個物件的函式。該物件包含可注入其子孫的屬性。在該物件中你可以使用 ES2015 Symbols 作為 key,但是隻在原生支援 Symbol 和 Reflect.ownKeys 的環境下可工作。

inject 選項應該是: 一個字串陣列,或 一個物件,物件的 key 是本地的繫結名,value 是: 在可用的注入內容中搜尋用的 key (字串或 Symbol),或 一個物件,該物件的: from 屬性是在可用的注入內容中搜尋用的 key (字串或 Symbol) default 屬性是降級情況下使用的 value

使用場景:由於vue有$parent屬性可以讓子元件訪問父元件。但孫元件想要訪問祖先元件就比較困難。通過provide/inject可以輕鬆實現跨級訪問祖先元件的資料

一種最常見的用法是重新整理vue元件 app.vue

<template>
  <div
    id="app"
  >
    <router-view
      v-if="isRouterAlive"
    />
  </div>
</template>

<script>
export default {
  name: 'App',
  components: {
    MergeTipDialog,
    BreakNetTip
  },
  data () {
    return {
      isShow: false,
      isRouterAlive: true
  },

// 父元件中返回要傳給下級的資料
  provide () {
    return {
      reload: this.reload
    }
  },
  methods: {
    reload () {
      this.isRouterAlive = false
      this.$nextTick(() => {
        this.isRouterAlive = true
      })
    }
  }
}
</script>
複製程式碼
<template>
  <popup-assign
    :id="id"
    @success="successHandle"
  >
    <div class="confirm-d-tit"><span class="gray-small-btn">{{ name }}</span></div>
    <strong>將被分配給</strong>
    <a
      slot="reference"
      class="unite-btn"
    >
      指派
    </a>
  </popup-assign>
</template>
<script>
import PopupAssign from '../PopupAssign'
export default {
//引用vue reload方法
  inject: ['reload'],
  components: {
    PopupAssign
  },
methods: {
    // ...mapActions(['freshList']),
    async successHandle () {
      this.reload()
    }
  }
}
</script>

複製程式碼

這樣就實現了子元件調取reload方法就實現了重新整理vue元件的功能,個人認為它實現了元件跨越元件傳遞資料方法。 下面一個例子祖元件的資料,祖孫元素調取 Ancestor.vue

<template>
	<div id="app">
	</div>
</template>
	<script>
		export default {
			data () {
					return {
						datas: [
							{
								id: 1,
								label: '產品一'
							},
							{
								id: 1,
								label: '產品二'
							},
							{
								id: 1,
								label: '產品三'
							}
						]
					}
			},
			provide {
				return {
					datas: this.datas
				}
			}
		}
	</script>
複製程式碼

後代元件

<template>
	<div>
		<ul>
		<li v-for="(item, index) in datas" :key="index">
			{{ item.label }}
		</li>
		</ul>
	</div>
</template>
	<script>
		export default {
			inject: ['datas']
		}
	</script>
複製程式碼

後代元素引入被注入資料datas,並在元件內迴圈輸出

實際上,你可以把依賴注入看作一部分“大範圍有效的 prop”,除了: 祖先元件不需要知道哪些後代元件使用它提供的屬性 後代元件不需要知道被注入的屬性來自哪裡

提示:provide 和 inject 繫結並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的物件,那麼其物件的屬性還是可響應的。

參考文獻:cn.vuejs.org/v2/api/#pro…

cn.vuejs.org/v2/guide/co…

相關文章