[vue3新特性] 9.組合api——10.Provide / Inject

之前我們學(xué)習(xí)過provide和inject的作用,就是在父級組件中provide數(shù)據(jù)或者方法,在他的后代組件中只要直接inject就可以使用這些數(shù)據(jù)或者方法了,
這節(jié)課我們就一起學(xué)習(xí)一下在組合API中使用provide和inject,還是以我們之前寫的titleBar組件為例

1.基本用法

在父組件中使用provide,需要先導(dǎo)入這個方法

import { provide } from 'vue'

provide這個函數(shù)有兩個參數(shù)

provide(name,value)

第一個參數(shù)就是數(shù)據(jù)或者方法的名字,第二個就是它的值,
我們在App.vue中給后代組件provide一個titleColor,表示標(biāo)題欄文字的顏色

  setup() {
    provide('titleColor', '#333')
  },

名字是titleColor,它的值是‘#333’
這樣在父組件中就完成了provide

下面來修改titleBar組件
inject也是一個方法,我們在titleBar中導(dǎo)入它

import { inject } from 'vue'

然后我們根據(jù)父組件中provide的名字獲取到它的值,
最后需要在setup中return這個值,以便在template中使用

  setup() {
    const titleColor = inject('titleColor')    // titleColor就是我們在父組件中provide的名字
    return {
      titleColor,
    }
  },

template中使用titleColor

<div class="title" :style="{ color: titleColor }">{{ title }}</div>

我們可以看到父組件中provide的顏色值渲染到了div這個元素上



inject這個方法還有第二個參數(shù),表示如果父級組件沒有provide相應(yīng)的數(shù)據(jù),那它默認(rèn)返回的值

inject(name,defaultValue)

現(xiàn)在我們把父組件中provide的titleColor去掉,
在titleBar組件中,inject時增加一個默認(rèn)值

const titleColor = inject('titleColor', 'red')

這樣我們我頁面標(biāo)題就變成了紅色


2.增加響應(yīng)性

現(xiàn)在我們恢復(fù)上一步的代碼,還是由App.vue來provide titleColor這個數(shù)據(jù),
我們現(xiàn)在來provide一個有響應(yīng)性的值,只需要用ref或者reactive來定義數(shù)據(jù)就行了
在App.vue中修改

const titleColor = ref('#333')
provide('titleColor', titleColor)

這樣titleColor這個數(shù)據(jù)就有響應(yīng)性了,
我們在onMounted中,改變它的值

  setup() {
    const titleColor = ref('#333')
    provide('titleColor', titleColor)

    onMounted(() => {
      titleColor.value = 'green'     // 改變了數(shù)據(jù)titleColor的值
    })
  },

在titleBar中的代碼不用修改,還是像以前一樣inject titleColor這個數(shù)據(jù)

  setup() {
    const titleColor = inject('titleColor', 'red')
    return {
      titleColor,
    }
  },

它接收到green這個值,覆蓋了它的默認(rèn)值red,所以最后頁面標(biāo)題的顏色是綠色的


3.子組件如何改變inject的值

如果我們想在子組件中改變父組件provide的titleColor這個值,不可以在子組件中直接修改,因為這樣會導(dǎo)致代碼邏輯混亂,降低代碼的可維護性,我們的原則是子級組件不要去改變父級組件的
這時正確的方式是在父組件中定義一個改變titleColor的方法,然后把這個方法provide給子組件
在App.vue中增加changeTitleColor這個方法

  setup() {
    const titleColor = ref('#333')
    const changeTitleColor = () => {   // 增加改變titleColor的方法
      titleColor.value = 'blue'
    }
    provide('titleColor', titleColor)
    provide('changeTitleColor', changeTitleColor)     // 把這個方法provide給子組件
  },

在子組件中調(diào)用changeTitleColor方法

  setup() {
    const titleColor = inject('titleColor', 'red')
    const changeTitleColor = inject('changeTitleColor')   // inject這個方法
    onMounted(() => {
      changeTitleColor()   //在組件掛載以后調(diào)用,就可以改變titleColor的值了
    })
    return {
      titleColor,
    }
  },

現(xiàn)在我們的頁面標(biāo)題變成了藍(lán)色



更進(jìn)一步,為了防止子組件中修改provide的數(shù)據(jù),可以在provide時使用readonly
在App.vue中導(dǎo)入readonly這個方法

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

在provide數(shù)據(jù)時,增加readonly

  setup() {
    const titleColor = ref('#333')
    const changeTitleColor = () => {
      titleColor.value = 'blue'
    }
    provide('titleColor', readonly(titleColor))    // 新增
    provide('changeTitleColor', changeTitleColor)
  },

這樣子組件中就不能更改titleColor的值了,我們可以更改一下試試,看看會怎么樣

  setup() {
    const titleColor = inject('titleColor', 'red')
    titleColor.value = 'blue'  // 更改titleColor,會有警告,而且更改也不會生效
    return {
      titleColor,
    }
  },

這樣寫時,控制臺會輸出一個警告



同時更改也不會有效果

這節(jié)課內(nèi)容就到這里,基本都是對provide/inject的一個復(fù)習(xí),只是寫法不一樣了而已。

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容