欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中provide、inject詳解以及使用教程

 更新時(shí)間:2022年11月14日 11:05:24   作者:明天也要努力  
provide和inject主要為高階插件/組件庫(kù)提供用例,并不推薦直接用于應(yīng)用程序代碼中,下面這篇文章主要給大家介紹了關(guān)于Vue中provide、inject詳解以及使用的相關(guān)資料,需要的朋友可以參考下

Vue中 常見的組件通信方式可分為三類

父子通信

父向子傳遞數(shù)據(jù)是通過(guò) props,子向父是通過(guò) events($emit);
通過(guò)父鏈 / 子鏈也可以通信($parent / $children);
ref 也可以訪問(wèn)組件實(shí)例;
provide / inject;
$attrs/$listeners;

兄弟通信

Bus;
Vuex;

跨級(jí)通信

Bus;
Vuex;
provide / inject、
$attrs / $listeners、

1. provide / inject 簡(jiǎn)介

類型

provide:Object | () => Object
inject: Array<string> | { [key: string]: string | Symbol | Object }

詳細(xì)

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

provide 選項(xiàng)應(yīng)該是一個(gè)對(duì)象或返回一個(gè)對(duì)象的函數(shù)。該對(duì)象包含可注入其子孫的 property。
在該對(duì)象中可使用 ES2015 Symbols 作為 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的環(huán)境下可工作。

inject 選項(xiàng)應(yīng)該是:
  一個(gè)字符串?dāng)?shù)組,或
  一個(gè)對(duì)象,對(duì)象的 key 是本地的綁定名,value 是:
      在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol),或
      一個(gè)對(duì)象,該對(duì)象的:
         from property 是在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol)
         default property 是降級(jí)情況下使用的 value

2. provide / inject 使用方法

祖組件

<template>
  <div>
    <button @click="changeMsg">祖組件觸發(fā)</button>
    <h1>祖組件</h1>
    <parent></parent>
  </div>
</template>

<script>
import parent from './parent.vue';
export default {
  data(){
    return{
      obj:{
        name:'JavaScript',
      },
      developer:'布蘭登·艾奇',
      year:1995,
      update:'2021年06月',
    }
  },
  provide(){
    return {
      obj: this.obj, // 方式1.傳入一個(gè)可監(jiān)聽的對(duì)象
      developerFn:() => this.developer, // 方式2.通過(guò) computed 來(lái)計(jì)算注入的值
      year: this.year, // 方式3.直接傳值
      app: this, // 4. 提供祖先組件的實(shí)例 缺點(diǎn):實(shí)例上掛載很多沒(méi)有必要的東西 比如:props,methods。
    }
  },
  components: {
    parent,
  },
  methods:{
    changeMsg(){
      this.obj.name = 'Vue';
      this.developer = '尤雨溪';
      this.year = 2014;
      this.update = '2021年6月7日';
    },
  },
}
</script>

父組件

<template>
  <div class="wrap">
    <h4>子組件(只做中轉(zhuǎn))</h4>
    <child></child>
  </div>
</template>

<script>
import child from './child.vue';
export default {
  components:{
    child,
  },
}
</script>

孫組件

<template>
  <div>
    <h5>孫組件</h5>
    <span>名稱:{{obj.name}}</span> |
    <span>作者:{{developer}}</span> |
    <span>誕生于:{{year}}</span> |
    <span>最后更新于:{{this.app.update}}</span>
  </div>
</template>
 
<script>
export default {
  computed:{
    developer(){
      return this.developerFn()
    }
  },
  inject:['obj','developerFn','year','app'],
}
</script>

未點(diǎn)擊按鈕,原有狀態(tài)

當(dāng)點(diǎn)擊按鈕觸發(fā) changeMsg 方法后,效果如下:

對(duì)比一下前后差異:無(wú)論點(diǎn)擊多少次,孫組件中的誕生于 year 字段永遠(yuǎn)都是1995 并不會(huì)發(fā)生變化,通過(guò) 方式1、方式2、方式4傳值是可以響應(yīng)的。

正是官網(wǎng)所提到的:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個(gè)可監(jiān)聽的對(duì)象,那么其對(duì)象的 property 還是可響應(yīng)的。

在孫組件中修改祖組件傳遞過(guò)來(lái)的值(方式1、方式4),發(fā)現(xiàn)對(duì)應(yīng)的祖組件中的值也發(fā)生了變化。

祖組件

<template>
  <div>
    <h1>祖組件</h1>
    <span>名稱:{{obj.name}}</span> |
    <span>最后更新于:{{update}}</span>
    <parent></parent>
  </div>
</template>

<script>
import parent from './parent.vue';
export default {
  data(){
    return{
      obj:{
        name:'JavaScript',
      },
      update:'2021年06月',
    }
  },
  provide(){
    return {
      obj: this.obj, 
      app: this,
    }
  },
  components: {
    parent,
  },
}
</script>

父組件不變

孫組件

<template>
  <div>
    <button @click="changeMsg">孫組件觸發(fā)</button>
    <h3>孫組件</h3>
    <span>名稱:{{obj.name}}</span> |
    <span>最后更新于:{{this.app.update}}</span>
  </div>
</template>
 
<script>
export default {
  inject:['obj','app'],
  methods: {
    changeMsg(){
      this.obj.name = 'React';
      this.app.update = '2020年10月';
    }
  },
}
</script>

未點(diǎn)擊按鈕,原有狀態(tài)

當(dāng)點(diǎn)擊按鈕觸發(fā) changeMsg 方法后,效果如下:

3. 總結(jié)

慎用 provide / inject

既然 provide/inject 如此好用,那么,為什么 Vue 官方還要推薦我們使用 Vuex,而不是用原生的 API 呢?
前面提到過(guò),Vuex 和 provide/inject 最大的區(qū)別:Vuex 中的全局狀態(tài)的每次修改是可以追蹤回溯的,而 provide/inject 中變量的修改是無(wú)法控制的。換句話說(shuō),不知道是哪個(gè)組件修改了這個(gè)全局狀態(tài)。
Vue 的設(shè)計(jì)理念借鑒了 React 中的單向數(shù)據(jù)流原則(雖然有 sync 這種破壞單向數(shù)據(jù)流的家伙),而 provide/inject 明顯破壞了單向數(shù)據(jù)流原則。試想,如果有多個(gè)后代組件同時(shí)依賴于一個(gè)祖先組件提供的狀態(tài),那么只要有一個(gè)組件修改了該狀態(tài),那么所有組件都會(huì)受到影響。這一方面增加了耦合度,另一方面,使得數(shù)據(jù)變化不可控。如果在多人協(xié)作開發(fā)中,這將成為一個(gè)噩夢(mèng)。

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

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

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

使用 provide / inject 編寫組件

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

以我們比較熟悉的 elementUI 來(lái)舉例:

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

如果是常規(guī)方案,我們可以通過(guò) props 從 Form 開始,一層層往下傳遞屬性值。看起來(lái)只需要傳遞傳遞兩層即可,還可以接受。但是,F(xiàn)orm 的下一層組件不一定是 FormItem,F(xiàn)ormItem 的下一層組件不一定是 Button,它們之間還可以嵌套其他組件,也就是說(shuō),層級(jí)關(guān)系不確定。如果使用 props,我們寫的組件會(huì)出現(xiàn)強(qiáng)耦合的情況。

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

部分源碼如下:

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

總結(jié)

到此這篇關(guān)于Vue中provide、inject詳解及使用的文章就介紹到這了,更多相關(guān)Vue provide、inject詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論