vue3中 provide 和 inject 用法及原理

前言:

在父子組件傳遞數據時,通常使用的是 props 和 emit,父傳子時,使用的是 props,如果是父組件傳孫組件時,就需要先傳給子組件,子組件再傳給孫組件,如果多個子組件或多個孫組件使用時,就需要傳很多次,會很麻煩。

像這種情況,可以使用 provide inject 解決這種問題,不論組件嵌套多深,父組件都可以為所有子組件或孫組件提供數據,父組件使用 provide 提供數據,子組件或孫組件 inject 註入數據。同時兄弟組件之間傳值更方便。

一、Vue2 的 provide / inject 使用

provide :是一個對象,裡面是屬性和值。如:

provide:{

 info:"值"

}

如果 provide 需要使用 data 內的數據時,這樣寫就會報錯。訪問組件實例 property 時,需要將 provide 轉換為返回對象的函數。

provide(){

 return{

  info: this.msg

 }

}

inject :是一個字符串數組。如:

inject: [ 'info' ]

接收上邊 provide 提供的 info 數據,也可以是一個對象,該對象包含 from 和 default 屬性,from 是可用做的註入內容中搜索用的 key,default 屬性是指定默認值。

在 vue2 中 project / inject 應用:

//父組件

export default{

 provide:{

  info:"提供數據"

 }

}

//子組件

export default{

 inject:['info'],

 mounted(){

     console.log("接收數據:", this.info) // 接收數據:提供數據

 }

} 

provide / inject 類似於消息的訂閱和發佈。provide 提供或發送數據, inject 接收數據。

二、Vue3 的 provide / inject 使用

在組合式 API 中使用 provide/inject,兩個隻能在 setup 期間調用,使用之前,必須從 vue 顯示導入 provide/inject 方法。

provide 函數接收兩個參數:

provide( name,value )

  • name:定義提供 property name
  • valueproperty 的值。

使用時:

import { provide } from "vue"

export default {

  setup(){

    provide('info',"值")

  }

}

inject 函數有兩個參數:

inject(name,default)

  • name:接收 provide 提供的屬性名。
  • default:設置默認值,可以不寫,是可選參數。

使用時:

import { inject } from "vue"

export default {

  setup(){

    inject('info',"設置默認值")

  }

}

完整實例1provide/inject實例

//父組件代碼

<script>

import { provide } from "vue"

export default {

  setup(){

    provide('info',"值")

  }

}

</script>

//子組件 代碼

<template>

 {{info}}

</template>

<script>

import { inject } from "vue"

export default {

  setup(){

    const info = inject('info')

    return{

      info

    }

  }

}

</script>

三、添加響應性

為瞭給 provide/inject 添加響應性,使用 ref reactive

完整實例2provide/inject 響應式

//父組件代碼

<template>

  <div>

    info:{{info}}

    <InjectCom ></InjectCom>

  </div>

</template>

<script>

import InjectCom from "./InjectCom"

import { provide,readonly,ref } from "vue"

export default {

  setup(){

    let info = ref("今天你學習瞭嗎?")

    setTimeout(()=>{

      info.value = "不找借口,立馬學習"

    },2000)

    provide('info',info)

    return{

      info

    }

  },

  components:{

    InjectCom

  }

}

</script>

// InjectCom 子組件代碼

<template>

 {{info}}

</template>

<script>

import { inject } from "vue"

export default {

  setup(){

    const info = inject('info')

    setTimeout(()=>{

      info.value = "更新"

    },2000)

    return{

      info

    }

  }

}

</script>

上述示例,在父組件或子組件都會修改 info 的值。

provide / inject 類似於消息的訂閱和發佈,遵循 vue 當中的單項數據流,什麼意思呢?就是數據在哪,修改隻能在哪,不能在數據傳遞處修改數據,容易造成狀態不可預測。

在訂閱組件內修改值的時候,可以被正常修改,如果其他組件也使用該值的時候,狀態容易造成混亂,所以需要在源頭上規避問題。

readonly 隻讀函數,使用之前需要引入,如果給變量加上 readonly 屬性,則該數據隻能讀取,無法改變,被修改時會發出警告,但不會改變值。

使用方法:

import { readonly } from "vue"

let info = readonly('隻讀info值')

setTimout(()=>{

 info="更新info" //兩秒後更新info的值

},2000)

運行兩秒後,瀏覽器發出警告,提示 info 值不可修改。

所以我們就給provide發射出去的數據,添加一個隻讀屬性,避免發射出去的數據被修改。

完整實例2的 provide 處添加 readonly 。

provide('info', readonly(info))

在子組件修改值的時候,會有一個隻讀提醒。

修改值的時候,還是需要在 provide 發佈數據的組件內修改數據,所以會在組件內添加修改方法,同時也發佈出去,在子組件處調用就可以瞭。

如:

//發佈

let info = ref("今天你學習瞭嗎?")

const changeInfo = (val)=>{

 info.value = val

}

provide('info',readonly(info))

provide('changeInfo',changeInfo)



//訂閱

const chang = inject('changeInfo')

chang('沖向前端工程師')

完整示例3:修改數據

// 父組件代碼

<template>

  <div>

    info:{{info}}

    <InjectCom ></InjectCom>

  </div>

</template>



<script>

import InjectCom from "./InjectCom"

import { provide,readonly,ref } from "vue"

export default {

  setup(){

    let info = ref("今天你學習瞭嗎?")

    const changeInfo = (val)=>{

      info.value = val

    }

    provide('info',readonly(info))

    provide('changeInfo',changeInfo)

    return{

      info

    }

  },

  components:{

    InjectCom

  }

}

</script>



//InjectCom 子組件代碼

<template>

  <div>

    <button @click="chang('沖向前端工程師')">更新值</button>

  </div>

</template>

<script>

import { inject } from "vue"

export default {

  setup(){

    const info = inject('info')

    const chang = inject('changeInfo')

    return{

      info,

      chang

    }

  }

}

</script>
 

到此這篇關於vue3provide inject 用法及原理的文章就介紹到這瞭,更多相關 vue3 中provide 和 inject 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: